hdu3549 Flow Problem(dinic算法和ISAP算法)
2016-01-30 20:56
309 查看
Flow Problem
Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 11855 Accepted Submission(s): 5631
[align=left]
[/align]
[align=left]Problem Description[/align]
Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.
[align=left]Input[/align]
The first line of input contains an integer T, denoting the number of test cases.
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)
[align=left]Output[/align]
For each test cases, you should output the maximum flow from source 1 to sink N.
[align=left]Sample Input[/align]
2
3 2
1 2 1
2 3 1
3 3
1 2 1
2 3 1
1 3 1
[align=left]Sample Output[/align]
Case 1: 1
Case 2: 2
ISAP算法代码:
#include<cstdio> #include<cstring> #include<queue> #include<iostream> #include<fstream> using namespace std; #define N 205 #define INF (1<<30) #define min(x,y) (x<y?x:y) int G ,num ,d ,pre ,n; queue<int> q; void bfs(){ memset(d,-1,sizeof(d)); memset(num,0,sizeof(num)); d =0;num[0]=1;q.push(n);int u; while(!q.empty()){ u=q.front();q.pop(); for(int i=1;i<=n;++i){ if(d[i]==-1&&G[i][u]>0){ d[i]=d[u]+1;q.push(i); ++num[d[i]]; } } } //printf("d:");for(int i=1;i<=n;++i) printf("%d ",d[i]);printf("\n"); } int augment(){ int u=n,res=INF; while(u!=1){ res=min(res,G[pre[u]][u]); u=pre[u]; }u=n; while(u!=1){ G[pre[u]][u]-=res; G[u][pre[u]]+=res; u=pre[u]; } //printf("res=%d\n",res); return res; } int isap(){ int ans=0,u=1,m;bfs();bool flag; while(d[u]<n){flag=true; if(u==n){ans+=augment();u=1;} for(int i=1;i<=n;++i){ if(d[i]+1==d[u]&&G[u][i]>0){ flag=false;pre[i]=u;u=i;break; } }//printf("u=%d\n",u); if(flag){m=n-1; for(int i=1;i<=n;++i){ if(G[u][i]>0&&d[i]!=-1) m=min(m,d[i]); } if(--num[d[u]]==0) break; ++num[d[u]=m+1]; if(u!=1) u=pre[u]; } } return ans; } int main(){ int m,u,v,w,Case=1,t;scanf("%d",&t); /*ifstream fin;fin.open("C:\\Users\\l\\Desktop\\Learning File\\Programing File\\check\\data.txt"); ofstream fout;fout.open("C:\\Users\\l\\Desktop\\Learning File\\Programing File\\check\\my.txt");*/ while(t--){ scanf("%d%d",&n,&m); memset(G,0,sizeof(G)); for(int i=0;i<m;++i){ //fin>>u>>v>>w; scanf("%d%d%d",&u,&v,&w); G[u][v]+=w; } printf("Case %d: %d\n",Case++,isap()); /*fout<<isap()<<endl; cout<<Case++<<" data run!"<<endl;*/ }//fin.close();fout.close(); return 0; }
dinic算法代码:
#include<cstdio> #include<cstring> #include<queue> using namespace std; #define N 20 #define INF (1<<30) #define min(x,y) (x<y?x:y) int G ,d ,n; queue<int> q; bool bfs(int s){ memset(d,-1,sizeof(d)); q.push(s);d[s]=0;int u; while(!q.empty()){ u=q.front();q.pop(); for(int i=1;i<=n;++i){ if(d[i]==-1&&G[u][i]>0){d[i]=d[u]+1;q.push(i);} } } if(d ==-1) return false; else return true; } int dinic(int s,int sum){ if(s==n) return sum; int k; for(int i=1;i<=n;++i){ if(d[s]+1==d[i]&&G[s][i]>0&&(k=dinic(i,min(sum,G[s][i])))!=0){ G[s][i]-=k;G[i][s]+=k;return k; } } } int main(){ int t,m,u,v,w,Case=1,ans;scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); memset(G,0,sizeof(G)); for(int i=0;i<m;++i){ scanf("%d%d%d",&u,&v,&w); G[u][v]+=w; }ans=0; while(bfs(1)) ans+=dinic(1,INF); printf("Case %d: %d\n",Case++,ans); } return 0; }之前dinic老是WA,原因就是写错了一个地方Orz。
k=dinic(i,min(sum,G[s][i])))!=0与<span style="font-family: 'Courier New';">k=dinic(i,min(sum,G[s][i]))!=0。。。</span>
<span style="font-family: 'Courier New';">因为赋值符号的优先级比不等于判断要低。。这个错误太隐蔽了。。Orz</span>
相关文章推荐
- HDU 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 5592 ZYB's Premutation 线段树(查找动态区间第K大)
- HDU 5240 Exam (好水的题)
- HDU5237 Base64 大模拟
- HDU 1000
- HDU 1001
- 【网络流-最大流-Dinic-建模】POJ3281 Dining:Pascal 解法
- Ford_Fulkerson算法
- 重标记与前移算法
- 2015-11-11 hdu新生赛 A题(AC)
- 2015-11-11 hdu新生赛 C题(结束后一发AC)