Drainage Ditches --网络流

① dinic

#include <bits/stdc++.h>
using namespace std;
const int N=2e2+10;
const int M=4e2+10;
const int inf=0x3f3f3f3f;
int head[N],cnt;
struct edge{
    
    
	int next,to,cap,flow;
}e[M];
void add(int u,int v,int cap,int flow){
    
    
	e[cnt].to=v;
	e[cnt].next=head[u];
	e[cnt].cap=cap;
	e[cnt].flow=flow;
	head[u]=cnt++;
}
int n,m;

//dinic
int d[N];
bool bfs(int st,int ed){
    
    
	memset(d,-1,sizeof d);
	d[st]=1;
	queue<int>que;
	que.push(st);
	while(!que.empty()){
    
    
		int u=que.front();que.pop();
		for(int i=head[u];~i;i=e[i].next){
    
    
			int v=e[i].to;
			if(d[v]==-1&&e[i].cap-e[i].flow>0){
    
    
				d[v]=d[u]+1;
				que.push(v);
			}
		}
	}
	return d[ed]>0;
}
int dfs(int x,int ed,int flow){
    
    
	if(x==ed) return flow;
	int tmp=flow;
	for(int i=head[x];~i;i=e[i].next){
    
    
		int v=e[i].to;
		if(d[v]==d[x]+1&&e[i].cap-e[i].flow>0){
    
    
			int t=dfs(v,ed,min(flow,e[i].cap-e[i].flow));
			e[i].flow+=t;
			e[i^1].flow-=t;
			flow-=t;
		}
	}
	return tmp-flow;
}
int dinic(int st,int ed){
    
    
	int sum=0;
	while(bfs(st,ed)){
    
    
		sum+=dfs(st,ed,inf);
	}
	return sum;
}


int main(){
    
    
	while(~scanf("%d %d",&m,&n)){
    
    
		memset(head,-1,sizeof head);cnt=0;
		for(int i=1;i<=m;++i){
    
    
			int u,v,w;
			scanf("%d %d %d",&u,&v,&w);
			add(u,v,w,0);
			add(v,u,0,0);
		}
		printf("%d\n",dinic(1,n));
	}
	return 0;
}

② ISAP

#include <bits/stdc++.h>
using namespace std;
const int N=2e2+10;
const int inf=0x3f3f3f3f;
struct Edge
{
    
    
    int from,to,cap,flow;
};
vector<Edge>edges;
vector<int>G[N];
void add(int from,int to,int cap)
{
    
    
    edges.push_back((Edge){
    
    from,to,cap,0});
    edges.push_back((Edge){
    
    to,from,0,0});
    int m=edges.size();
    G[from].push_back(m-2);
    G[to].push_back(m-1);
}

// ISAP
int n,m,s,t;
int d[N],cur[N];
int pre[N],num[N];
int Augment()
{
    
    
    int x=t,ans=inf;
    while(x!=s)
    {
    
    
        Edge &e=edges[pre[x]];
        ans=min(ans,e.cap-e.flow);
        x=edges[pre[x]].from;
    }
    x=t;
    while(x!=s)
    {
    
    
        edges[pre[x]].flow+=ans;
        edges[pre[x]^1].flow-=ans;
        x=edges[pre[x]].from;
    }
    return ans;
}
void bfs()
{
    
    
    memset(d,-1,sizeof d);
    queue<int>q;
    q.push(t);
    d[t]=0;
    while(!q.empty())
    {
    
    
        int x=q.front();q.pop();
        int len=G[x].size();
        for(int i=0;i<len;i++)
        {
    
    
            Edge &e=edges[G[x][i]^1];
            if(d[e.from]==-1&&e.cap>e.flow)
            {
    
    
                d[e.from]=d[x]+1;
                q.push(e.from);
            }
        }
    }
}
int Maxflow()
{
    
    
    bfs();
    memset(num,0,sizeof(num));
    memset(cur,0,sizeof(cur));
    for(int i=1;i<=n;++i) ++num[d[i]];
    int x=s,flow=0;
    while(d[s]<n)
    {
    
    
        if(x==t)
        {
    
    
            flow+=Augment();
            x=s;
        }
        bool ok=false;
        for(int i=cur[x];i<G[x].size();i++)
        {
    
    
            Edge &e=edges[G[x][i]];
            if(e.cap>e.flow&&d[x]==d[e.to]+1)
            {
    
    
                ok=true;
                pre[e.to]=G[x][i];
                cur[x]=i;
                x=e.to;
                break;
            }
        }
        if(!ok)
        {
    
    
            int tmp=n-1;  //最大的d[s] 
            for(int i=0;i<G[x].size();++i)
            {
    
    
                Edge &e=edges[G[x][i]];
                if(e.cap>e.flow)
                    tmp=min(tmp,d[e.to]);
            }
            if(--num[d[x]]==0)break;
            ++num[d[x]=tmp+1];
            cur[x]=0;
            if(x!=s)
                x=edges[pre[x]].from;
        }
    }
    return flow;
}


void init(){
    
    
	edges.clear();
	for(int i=1;i<=n;++i) G[i].clear();
}
int main(){
    
    
	while(~scanf("%d %d",&m,&n)){
    
    
		init();
		for(int i=1;i<=m;++i){
    
    
			int u,v,w;scanf("%d %d %d",&u,&v,&w);
			add(u,v,w);
		}
		s=1,t=n;
		printf("%d\n",Maxflow());
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/bloom_er/article/details/107726566