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

posted on 2012-08-17 17:13  矮人狙击手!  阅读(422)  评论(0编辑  收藏  举报

导航