用dinic做的,20分,后面全是TLE,求带佬指导
查看原帖
用dinic做的,20分,后面全是TLE,求带佬指导
267888
AlexanderC楼主2021/2/25 12:03

Dfs的时候让所有叶子结点与n+1结点建边,然后跑rt和n+1之间的dinic,结果tle比较重,不知道怎么优化,求指导。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define INF 1e18
#define maxv 100500
#define maxe 300500
#define maxlogv 10 
#define rep(i,a,n) for(register int i=a;i<n;++i)
typedef long long ll;
using namespace std;
ll n,m,q,u,v,w,s,t,rt;
namespace network_flow{ 
    struct edge{
        ll to,next,flow;
    }E[maxe<<2];
    int head[maxv];
    int deep[maxv];
    int sz=1;
    void add(ll u,ll v,ll w){
        E[++sz]={v,head[u],w};
        head[u]=sz;
        E[++sz]={u,head[v],0};
        head[v]=sz;
    }
    bool bfs(ll s,ll t){
        memset(deep,0,sizeof(deep));
        deep[s]=1;
        queue<int>q;
        q.push(s);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=head[x];i;i=E[i].next){
                int y=E[i].to;
                if(!deep[y]&&E[i].flow){
                    deep[y]=deep[x]+1;
                    q.push(y);
                }
            }
        }
        return deep[t]!=0;
    }
    ll dfs(ll x,ll t,ll minf){
        if(x==t) return minf;
        ll k,rest=minf;
        for(int i=head[x];i;i=E[i].next){
            int y=E[i].to;
            if(deep[y]==deep[x]+1&&E[i].flow){
                k=dfs(y,t,min(rest,E[i].flow));
                rest-=k;
                E[i].flow-=k;
                E[i^1].flow+=k;
                if(k==0) deep[y]=0;
                if(rest==0) break;
            }
        } 
        return minf-rest;
    }
    void init(){
        for(int i=2;i<=sz;i+=2){
            E[i].flow=(E[i].flow+E[i^1].flow);
            E[i^1].flow=0;
        }
    }
    ll dinic(ll s,ll t){
        init();
        ll ans=0,now=0;
        while(bfs(s,t)){
            while(now=dfs(s,t,INF)) ans+=now;
        }
        return ans;
    }
    void Dfs(ll x,ll t,ll fa){
		bool flag=1;
		for(int i=head[x];i;i=E[i].next){
			ll to=E[i].to;
			if(to!=fa && to!=t) flag=0,Dfs(to,t,x);
		}
		if(flag) add(x,t,INF);
	}
} 

int main(){
	cin>>n>>rt;
	rep(i,1,n){
		cin>>u>>v>>w;
		network_flow::add(u,v,w);
		network_flow::add(v,u,w);
	}
	network_flow::Dfs(rt,n+1,0ll);				//空汇点与叶子结点建边 
	cout<<network_flow::dinic(rt,n+1);
	return 0;
}
2021/2/25 12:03
加载中...