网络流--最大流--Dinic模板矩阵版(当前弧优化+非当前弧优化)

mac2024-10-27  15

//非当前弧优化版 #include <iostream> #include <cstdio> #include <math.h> #include <cstring> #include <queue> #define INF 0x3f3f3f3f using namespace std; int tab[250][250];//邻接矩阵 int dis[250];//距源点距离,分层图 int N,M;//N:点数;M,边数 queue<int> Q; int BFS() { memset(dis,0xff,sizeof(dis));//以-1填充 dis[1]=0; Q.push(1); while (Q.size()) { int head=Q.front(); Q.pop(); for (int i=1; i<=N; i++) if (dis[i]<0 && tab[head][i]>0) { dis[i]=dis[head]+1; Q.push(i); } } if (dis[N]>0) return 1; else return 0;//汇点的DIS小于零,表明BFS不到汇点 } //dfs代表一次增广,函数返回本次增广的流量,返回0表示无法增广 int dfs(int x,int low)//Low是源点到现在最窄的(剩余流量最小)的边的剩余流量 { int a=0; if (x==N) return low;//是汇点 for (int i=1; i<=N; i++) if (tab[x][i] >0 //联通 && dis[i]==dis[x]+1 //是分层图的下一层 &&(a=dfs(i,min(low,tab[x][i]))))//能到汇点(a != 0) { tab[x][i]-=a; tab[i][x]+=a; return a; } return 0; } int dinic() { int ans=0,tans; while (BFS())//要不停地建立分层图,如果BFS不到汇点才结束 { while(tans=dfs(1,0x7fffffff))ans+=tans;//一次BFS要不停地找增广路,直到找不到为止 } return ans; } int main() { int i,j,f,t,flow,tans; while (scanf("%d%d",&M,&N)!=EOF) { memset(tab,0,sizeof(tab)); for (i=1; i<=M; i++) { scanf("%d%d%d",&f,&t,&flow); tab[f][t]+=flow; } printf("%d\n",dinic()); } } //当前弧优化版 #include <iostream> #include <cstdio> #include <math.h> #include <cstring> #include <queue> #define INF 0x3f3f3f3f using namespace std; int tab[250][250];//邻接矩阵 int dis[250];//距源点距离,分层图 int cur[280]; //当前弧优化 int N,M;//N:点数;M,边数 queue<int> Q; int BFS() { memset(dis,0xff,sizeof(dis));//以-1填充 dis[1]=0; Q.push(1); while (Q.size()) { int head=Q.front(); Q.pop(); for (int i=1; i<=N; i++) if (dis[i]<0 && tab[head][i]>0) { dis[i]=dis[head]+1; Q.push(i); } } if (dis[N]>0) return 1; else return 0;//汇点的DIS小于零,表明BFS不到汇点 } //dfs代表一次增广,函数返回本次增广的流量,返回0表示无法增广 int dfs(int x,int low)//Low是源点到现在最窄的(剩余流量最小)的边的剩余流量 { int a=0; if (x==N) return low;//是汇点 for (int &i=cur[x]; i<=N; i++) if (tab[x][i] >0 //联通 && dis[i]==dis[x]+1 //是分层图的下一层 &&(a=dfs(i,min(low,tab[x][i]))))//能到汇点(a != 0) { tab[x][i]-=a; tab[i][x]+=a; return a; } return 0; } int dinic() { int ans=0,tans; while (BFS())//要不停地建立分层图,如果BFS不到汇点才结束 { for(int i=1;i<=N;i++) cur[i]=1; while(tans=dfs(1,0x7fffffff))ans+=tans;//一次BFS要不停地找增广路,直到找不到为止 } return ans; } int main() { int i,j,f,t,flow,tans; while (scanf("%d%d",&M,&N)!=EOF) { memset(tab,0,sizeof(tab)); for (i=1; i<=M; i++) { scanf("%d%d%d",&f,&t,&flow); tab[f][t]+=flow; } printf("%d\n",dinic()); } }

 

风骨散人Chiam 认证博客专家 拖更专业户???? 大学僧,考研狗,没上岸,ACM退役选手。名字的含义:希望可以通过努力,能力让家人拥有富足的生活而不是为了生计而到处奔波。“世人慌慌张张,不过是图碎银几两。偏偏这碎银几两,能解世间惆怅,可让父母安康,可护幼子成长 …”Chiam是 -am爱 China中国文章主要内容:Python,C++,C语言,JAVA,C#等语言的教程,ACM题解、模板、算法等,主要是数据结构,数学和图论设计模式,数据库,计算机网络,操作系统,计算机组成原理,Python爬虫、深度学习、机器学学习,计算机系408考研的所有专业课内容。目前还在更新中,博客园,微信公众号同名“风骨散人”,关注公众号可获软件大礼包
最新回复(0)