hdu-4289 最大流Dinic模板题
拆点,套模板。
详情见代码。
// // main.cpp // hdu_4289 // // Created by Luke on 16/8/29. // Copyright © 2016年 Luke. All rights reserved. // //hdu-4289 #include <iostream> #include <vector> #include <queue> #define N 500 //开两倍大小多一些 #define INF 0x3f3f3f3f #define LL long long int using namespace std; int n,m;//点边 struct Node { int to; LL cap; unsigned long rev; }; LL Min(LL a,LL b) { return a>b?b:a; } vector<Node> g[N]; int level[N];//用来存放bfs查找最短路的标号 int itor[N];//弧优化 void bfs(LL now)//预先进行广度优先搜索,避免dfs中大量无效查找 { fill(level,level+(n<<1)+1,-1);//初始化为-1 level[now]=0; queue<LL> q; q.push(now); while(!q.empty()) { now=q.front(),q.pop(); for(int i=0;i<g[now].size();i++) { Node &e=g[now][i]; if(e.cap>0&&level[e.to]<0) level[e.to]=level[now]+1,q.push(e.to);//迭代标号 } } } LL dfs(LL now,LL en,LL f) { if(now==en) return f; for(int &i=itor[now];i<g[now].size();i++)//弧优化,用&迭代标号,使每次查找边跳过查找过的边 { Node &e=g[now][i]; if(e.cap>0&&level[e.to]>level[now])//如果level不满足肯定不需要查找 { LL temp=dfs(e.to,en,Min(f,e.cap)); if(temp>0) { e.cap-=temp; g[e.to][e.rev].cap+=temp; return temp; } } } return 0; } void addEdge(int from,int to,LL cap) { g[from].push_back((Node){to,cap,g[to].size()}); g[to].push_back((Node){from,0,g[from].size()-1}); } void ini() { for(int i=0;i<=(n<<1)+1;i++) g[i].clear(); //fill(used,used+n+1,0); } LL solve(LL s,LL en) { LL ans=0; while(1) { bfs(s); if(level[en]<0)//最短路未查找到路径,返回 return ans; fill(itor,itor+(n<<1)+1,0); LL d; while((d=dfs(s,en,INF))>0) ans+=d; } return ans; } int main(int argc, const char * argv[]) { cin.sync_with_stdio(false); while(cin>>n>>m) {//本题权值在端点处,把点拆分成线段 ini(); LL s,e; int num,num2; cin>>s>>e; e+=n; for(int i=1;i<=n;i++) cin>>num,addEdge(i, i+n, num),addEdge(i+n,i,num); for(int i=0;i<m;i++) cin>>num>>num2,addEdge(num+n, num2, INF),addEdge(num2+n,num,INF);//这里反向加边时一定要注意始末位置 cout<<solve(s,e)<<endl; } return 0; }