poj1459(网络流)
这道题跟我前面写的那两道网络流的题差不多,刚开始被题的描述吓到了,后来发现稍微变动下,原来的代码还可以继续用
是这样的,原来的问题都是单源单汇问题,这题是多源多汇,关键在于把多源多汇问题转化为单源单汇,只要构造一个超级源点和一个超级汇点就ok了,把超级源点和各个源点之间加一条边,把各个汇点和超级汇点之间加一条边,这样就ok了,其实很简单
关于最大流的问题我只会这一种方法,其他还有spa,ek ,以及spa算法的优化问题,这些最好都学习下
1 #include <cstdio> 2 #include <cstring> 3 #define Max 0x7f7f7f7f 4 int n,m; 5 int path[105][105]; 6 int visited[105]; 7 int que[10000]; 8 int pre[105]; 9 int flow[105]; 10 int min(int a ,int b) 11 { 12 return a>b?b:a; 13 } 14 int BFS(int n)//查找有没有增广路 15 { 16 memset(visited,0,sizeof(visited)); 17 memset(pre,-1,sizeof(pre)); 18 memset(flow,Max,sizeof(flow)); 19 int head=0; 20 int tail=1; 21 que[head]=1; 22 visited[1]=1; 23 while(head<tail) 24 { 25 int tmp=que[head]; 26 if(tmp==n) break; 27 for(int i=2;i<=n;i++) 28 { 29 if(visited[i]==0 && path[tmp][i]!=0) 30 { 31 visited[i]=1; 32 pre[i]=tmp; 33 que[tail]=i; 34 flow[i]=min(flow[tmp],path[tmp][i]); 35 tail++; 36 37 } 38 } 39 head++; 40 } 41 if(visited[n]==0) 42 return -1; 43 else return flow[n];//有增广路 44 } 45 46 int Ford_Fulkerson(int n) 47 { 48 int nowflow,maxflow=0; 49 while((nowflow=BFS(n))!=-1)//更新残余网络 50 { 51 maxflow+=nowflow; 52 int tmp=n; 53 while(tmp!=1) 54 { 55 int before=pre[tmp]; 56 path[before][tmp]-=nowflow; 57 path[tmp][before]+=nowflow; 58 tmp=before; 59 } 60 } 61 return maxflow; 62 } 63 64 65 int main() 66 { 67 int nodenum; 68 int power, consumer, link; 69 int start, end, cost; 70 int answer; 71 while(scanf("%d", &nodenum) != EOF) 72 { 73 //CLR(maze, 0); 74 memset(path,0,sizeof(path)); 75 scanf("%d%d%d", &power, &consumer, &link); 76 for(int i = 0; i < link; ++i) 77 { 78 scanf(" (%d,%d)%d", &start, &end, &cost); 79 if(start == end) 80 continue; 81 start += 2, end += 2; 82 path[start][end] += cost; 83 } 84 for(int i = 0; i < power; ++i) //超级源点 85 { 86 scanf(" (%d)%d", &end, &cost); 87 end += 2; 88 path[1][end] += cost; 89 } 90 for(int i = 0; i < consumer; ++i) //超级汇点 91 { 92 scanf(" (%d)%d", &start, &cost); 93 start += 2; 94 int res = nodenum + 2; 95 path[start][res] += cost; 96 } 97 answer = Ford_Fulkerson(nodenum + 2); 98 printf("%d\n", answer); 99 } 100 return 0; 101 102 }
更正下,上面的算法不叫Ford_Fulkerson ,应该叫做EK