您的位置:首页 > 其它

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息