• 「模板」网络最大流 FF && EK && Dinic && SAP && ISAP


    <题目链接>

    话不多说上代码。

    Ford-Fulkerson(FF)

    #include <algorithm>
    #include <climits>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int MAXN=100010,MAXM=200010;
    bool vis[MAXN];
    int n,m,S,T,cnt,ans,head[MAXN];
    struct edge
    {
    	int nxt,to,w;
    }e[MAXM];
    void AddEdge(int x,int y,int w)
    {
    	e[++cnt].nxt=head[x];
    	e[cnt].to=y;
    	e[cnt].w=w;
    	head[x]=cnt;
    }
    void AddEdges(int x,int y,int w)
    {
    	AddEdge(x,y,w);
    	AddEdge(y,x,0);
    }
    int DFS(int x,int k)
    {
    	if(x==T)
    		return k;
    	vis[x]=1;
    	for(int i=head[x],t,f;i;i=e[i].nxt)
    		if(!vis[t=e[i].to] && e[i].w && (f=DFS(t,min(k,e[i].w))))
    		{
    			e[i].w-=f;
    			e[((i-1)^1)+1].w+=f;
    			return f;
    		}
    	return 0;
    }
    void FF()
    {
    	int f;
    	while(memset(vis,0,sizeof vis),f=DFS(S,INT_MAX))
    		ans+=f;
    	while(0,1)
    		printf("233");
    	while(1)
    	{
    		memset(vis,0,sizeof vis);
    		f=DFS(S,INT_MAX);
    		if(!f)
    			break;
    		ans+=f;
    	}
    }
    int main(int argc,char *argv[])
    {
    	scanf("%d %d %d %d",&n,&m,&S,&T);
    	for(int i=1,x,y,w;i<=m;++i)
    	{
    		scanf("%d %d %d",&x,&y,&w);
    		AddEdges(x,y,w);
    	}
    	FF();
    	printf("%d
    ",ans);
    	return 0;
    }
    

    Edmonds-Karp(EK)

    #include <algorithm>
    #include <climits>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int MAXN=10010,MAXM=200010;
    int n,m,S,T,cnt,ans,head[MAXN],flow[MAXN],pre[MAXN],pre_e[MAXN];
    struct edge
    {
    	int nxt,to,w;
    }e[MAXM];
    void AddEdge(int x,int y,int w)
    {
    	e[++cnt].nxt=head[x];
    	e[cnt].to=y;
    	e[cnt].w=w;
    	head[x]=cnt;
    }
    void AddEdges(int x,int y,int w)
    {
    	AddEdge(x,y,w);
    	AddEdge(y,x,0);
    }
    bool BFS(int S)
    {
    	queue<int> q;
    	memset(flow,0x7f,sizeof flow);
    	memset(pre,0,sizeof pre);
    	memset(pre_e,0,sizeof pre_e);
    	q.push(S);
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		for(int i=head[x],t;i;i=e[i].nxt)
    			if(!pre[t=e[i].to] && e[i].w)
    			{
    				q.push(t);
    				pre[t]=x;
    				pre_e[t]=i;
    				flow[t]=min(flow[x],e[i].w);
    			}
    		if(pre[T])
    			return 1;
    	}
    	return 0;
    }
    void EK()
    {
    	while(BFS(S))
    	{
    		for(int i=T,t;i!=S;i=pre[i])
    		{
    			e[t=pre_e[i]].w-=flow[T];
    			e[((t-1)^1)+1].w+=flow[T];
    		}
    		ans+=flow[T];
    	}
    }
    int main(int argc,char *argv[])
    {
    	scanf("%d %d %d %d",&n,&m,&S,&T);
    	for(int i=1,x,y,w;i<=m;++i)
    	{
    		scanf("%d %d %d",&x,&y,&w);
    		AddEdges(x,y,w);
    	}
    	EK();
    	printf("%d",ans);
    	return 0;
    }
    

    Dinic

    #include <algorithm>
    #include <climits>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int MAXN=10010,MAXM=200010;
    bool vis[MAXN];
    int n,m,S,T,cnt,ans,head[MAXN],dis[MAXN],cur[MAXN];
    struct edge
    {
    	int nxt,to,w;
    }e[MAXM];
    void AddEdge(int x,int y,int w)
    {
    	e[++cnt].nxt=head[x];
    	e[cnt].to=y;
    	e[cnt].w=w;
    	head[x]=cnt;
    }
    void AddEdges(int x,int y,int w)
    {
    	AddEdge(x,y,w);
    	AddEdge(y,x,0);
    }
    bool BFS(int S)
    {
    	queue<int> q;
    	memset(dis,0,sizeof dis);
    	vis[S]=1;
    	q.push(S);
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		for(int i=head[x],t;i;i=e[i].nxt)
    			if(!vis[t=e[i].to] && e[i].w)
    			{
    				vis[t]=1;
    				q.push(t);
    				dis[t]=dis[x]+1;
    			}
    		if(dis[T])
    			return 1;
    	}
    	return 0;
    }
    int DFS(int x,int k)
    {
    	if(x==T)
    		return k;
    	for(int i=cur[x],t,f;i;i=e[i].nxt)
    		if(dis[t=e[i].to]==dis[x]+1 && e[i].w && (f=DFS(t,min(k,e[i].w))))
    		{
    			e[i].w-=f;
    			e[((i-1)^1)+1].w+=f;
    			cur[x]=i;
    			return f;
    		}
    	return 0;
    }
    void Dinic()
    {
    	int f;
    	while(memset(vis,0,sizeof vis),BFS(S))
    		while(memcpy(cur,head,sizeof head),f=DFS(S,INT_MAX))
    			ans+=f;
    }
    int main(int argc,char *argv[])
    {
    	scanf("%d %d %d %d",&n,&m,&S,&T);
    	for(int i=1,x,y,w;i<=m;++i)
    	{
    		scanf("%d %d %d",&x,&y,&w);
    		AddEdges(x,y,w);
    	}
    	Dinic();
    	printf("%d",ans);
    	return 0;
    }
    

    Shortest Augmenting Path(SAP)

    #include <algorithm>
    #include <climits>
    #include <cstdio>
    #include <queue>
    using namespace std;
    const int MAXN=10010,MAXM=200010;
    bool vis[MAXN];
    int n,m,S,T,cnt,ans,head[MAXN],cur[MAXN],pre[MAXN],pre_e[MAXN],dis[MAXN],gap[MAXN];
    struct edge
    {
    	int nxt,to,w;
    }e[MAXM];
    void AddEdge(int x,int y,int w)
    {
    	e[++cnt].nxt=head[x];
    	e[cnt].to=y;
    	e[cnt].w=w;
    	head[x]=cur[x]=cnt;
    }
    void AddEdges(int x,int y,int w)
    {
    	AddEdge(x,y,w);
    	AddEdge(y,x,0);
    }
    void BFS(int T)
    {
    	queue<int> q;
    	q.push(T);
    	vis[T]=1;
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		for(int i=head[x],t;i;i=e[i].nxt)
    			if(!dis[t=e[i].to] && !e[i].w)
    			{
    				vis[t]=1;
    				dis[t]=dis[x]+1;
    				q.push(t);
    			}
    	}
    }
    int Flow()
    {
    	int f=INT_MAX;
    	for(int i=T;i!=S;i=pre[i])
    		f=min(f,e[pre_e[i]].w);
    	for(int i=T,t;i!=S;i=pre[i])
    	{
    		e[t=pre_e[i]].w-=f;
    		e[((t-1)^1)+1].w+=f;
    	}
    	return f;
    }
    void SAP()
    {
    	BFS(T);
    	for(int i=1;i<=n;++i)
    		++gap[dis[i]];
    	int x=S;
    	while(dis[S]<n)
    	{
    		if(x==T)
    		{
    			ans+=Flow();
    			x=S;
    		}
    		bool flag=0;
    		for(int i=cur[x],t;i;i=e[i].nxt)
    			if(e[i].w && dis[x]==dis[t=e[i].to]+1)
    			{
    				flag=1;
    				pre[t]=x;
    				pre_e[t]=cur[x]=i;
    				x=t;
    				break;
    			}
    		if(!flag)
    		{
    			if(!--gap[dis[x]])
    				break;
    			int f=n-1;
    			for(int i=head[x];i;i=e[i].nxt)
    				if(e[i].w)
    					f=min(f,dis[e[i].to]);
    			++gap[dis[x]=f+1];
    			cur[x]=head[x];
    			if(x!=S)
    				x=pre[x];
    		}
    	}
    }
    int main(int argc,char *argv[])
    {
    	scanf("%d %d %d %d",&n,&m,&S,&T);
    	for(int i=1,x,y,w;i<=m;++i)
    	{
    		scanf("%d %d %d",&x,&y,&w);
    		AddEdges(x,y,w);
    	}
    	SAP();
    	printf("%d",ans);
    	return 0;
    }
    

    Improved Shortest Augmenting Path(ISAP)

    #include <algorithm>
    #include <climits>
    #include <cstdio>
    using namespace std;
    const int MAXN=10010,MAXM=200010;
    int n,m,S,T,cnt,ans,head[MAXN],cur[MAXN],pre[MAXN],pre_e[MAXN],dis[MAXN],gap[MAXN];
    struct edge
    {
    	int nxt,to,w;
    }e[MAXM];
    void AddEdge(int x,int y,int w)
    {
    	e[++cnt].nxt=head[x];
    	e[cnt].to=y;
    	e[cnt].w=w;
    	head[x]=cur[x]=cnt;
    }
    void AddEdges(int x,int y,int w)
    {
    	AddEdge(x,y,w);
    	AddEdge(y,x,0);
    }
    int Flow()
    {
    	int f=INT_MAX;
    	for(int i=T;i!=S;i=pre[i])
    		f=min(f,e[pre_e[i]].w);
    	for(int i=T,t;i!=S;i=pre[i])
    	{
    		e[t=pre_e[i]].w-=f;
    		e[((t-1)^1)+1].w+=f;
    	}
    	return f;
    }
    void ISAP()
    {
    	for(int i=1;i<=n;++i)
    		++gap[dis[i]];
    	int x=S;
    	while(dis[S]<n)
    	{
    		if(x==T)
    		{
    			ans+=Flow();
    			x=S;
    		}
    		bool flag=0;
    		for(int i=cur[x],t;i;i=e[i].nxt)
    			if(e[i].w && dis[x]==dis[t=e[i].to]+1)
    			{
    				flag=1;
    				pre[t]=x;
    				pre_e[t]=cur[x]=i;
    				x=t;
    				break;
    			}
    		if(!flag)
    		{
    			if(!--gap[dis[x]])
    				break;
    			int f=n-1;
    			for(int i=head[x];i;i=e[i].nxt)
    				if(e[i].w)
    					f=min(f,dis[e[i].to]);
    			++gap[dis[x]=f+1];
    			cur[x]=head[x];
    			if(x!=S)
    				x=pre[x];
    		}
    	}
    }
    int main(int argc,char *argv[])
    {
    	scanf("%d %d %d %d",&n,&m,&S,&T);
    	for(int i=1,x,y,w;i<=m;++i)
    	{
    		scanf("%d %d %d",&x,&y,&w);
    		AddEdges(x,y,w);
    	}
    	ISAP();
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    剑指offer——最小的K个数和数组中第K大的元素
    Leetcode刷题指南链接整理
    160. Intersection of Two Linked Lists
    100. Same Tree
    92. Reverse Linked List II
    94. Binary Tree Inorder Traversal
    79. Word Search
    78,90,Subsets,46,47,Permutations,39,40 DFS 大合集
    0x16 Tire之最大的异或对
    0x16 Tire
  • 原文地址:https://www.cnblogs.com/Capella/p/8032583.html
Copyright © 2020-2023  润新知