poj1459 Power Network (最大流)

多源最大流问题,可以构造成一般最大流问题,增加一个起点和一个终点。起点指向每个Power station,边的权值为Power station的Pmax。每个Consumer指向终点,边的权值为Cmax。Dispatcher看做一般节点。

用EK算法算法实现的版本,Time:766MS

ContractedBlock.gif ExpandedBlockStart.gif Code
  1 #include <iostream>
  2 #include <stdio.h>
  3 #define SIZE 103
  4 using namespace std;
  5 
  6 int n, np, nc, m, source, sink;
  7 int map[SIZE][SIZE];
  8 //FIFO queue============================================
  9 struct QUEUE{
 10     int queue[SIZE];
 11     int head;
 12     int tail;
 13 };
 14 struct QUEUE q;
 15 int color[SIZE], par[SIZE];
 16 
 17 int InitQ(){
 18     q.head=q.tail=0;
 19     return 1;
 20 }
 21 int EnQ(int x){
 22     q.queue[q.tail]=x;
 23     q.tail++;
 24     return 1;
 25 }
 26 int DeQ(){
 27     int x;
 28     x=q.queue[q.head];
 29     q.head++;
 30     return x;
 31 }
 32 //=====================================================
 33 int BFSSearchPath()
 34 {
 35     int i, u, v, flag;
 36     flag=0;
 37     InitQ();
 38     for (i=1;i<=n;i++){
 39         color[i]=0;
 40         par[i]=-1;
 41     }
 42     color[source]=1;
 43     par[source]=-1;
 44     EnQ(source);
 45     while (q.head!=q.tail && !flag){
 46         u=DeQ();
 47         for (v=0;v<=n;v++){
 48             if (map[u][v]!=0 && color[v]==0){
 49                 color[v]=1;
 50                 par[v]=u;
 51                 EnQ(v);
 52                 if (v==sink){//搜索到最短路径时返回
 53                     flag=1;
 54                     break;
 55                 }
 56             }
 57         }
 58         color[u]=2;
 59     }
 60     return flag;
 61 }
 62 int Edmonds_Karp()
 63 {
 64     int max, min, v;
 65     max=0;
 66     while (BFSSearchPath()){
 67         min=1001;
 68         v=sink;
 69         //求最短路径上的剩余流量
 70         while (v!=source){
 71             if (map[par[v]][v]<min){
 72                 min=map[par[v]][v];
 73             }
 74             v=par[v];
 75         }
 76         //根据剩余流量求剩余网络
 77         v=sink;
 78         while (v!=source){
 79             map[par[v]][v]-=min;
 80             map[v][par[v]]+=min;
 81             v=par[v];
 82         }
 83         max+=min;
 84     }
 85     return max;
 86 }
 87 int main()
 88 {
 89     int i, u, v, w, Con;
 90     char c;
 91     //freopen("input.txt", "r", stdin);
 92     source=0;
 93     while (cin>>n>>np>>nc>>m){
 94         memset(map, 0sizeof(map));
 95         for (i=0;i<m;i++){
 96             while (c=getchar()!='(');
 97             cin>>u;
 98             getchar();
 99             cin>>v;
100             getchar();
101             cin>>w;
102             map[u+1][v+1]=w;//node's index start from 1
103         }
104         sink=n+1;
105         n+=2;                //add the source and sink
106         m+=(np+nc);            //add new edges
107         for (i=0;i<np;i++){
108             while (c=getchar()!='(');
109             cin>>u;
110             getchar();
111             cin>>w;
112             map[source][u+1]=w;
113         }
114         for (i=0;i<nc;i++){
115             while (c=getchar()!='(');
116             cin>>u;
117             getchar();
118             cin>>w;
119             map[u+1][sink]=w;
120         }
121         Con=Edmonds_Karp();
122         cout<<Con<<endl;
123     }
124     return 0;
125 }
126 

 又用Dinic算法实现了一次,Time:438MS ,时间果然有很大提高

ContractedBlock.gif ExpandedBlockStart.gif Code
  1 //AC T:438MS
  2 #include <iostream>
  3 #include <list>
  4 #define GSIZE 103
  5 #define INF 10000000
  6 using namespace std;
  7 int src, sink, n, np, nc, m;
  8 int map[GSIZE][GSIZE], level[GSIZE], color[GSIZE];
  9 int OutDegree(int x)
 10 {
 11     int i;
 12     for (i=0;i<=n;i++){
 13         if (map[x][i]!=0 && level[x]+1==level[i])
 14             return i;
 15     }
 16     return 0;
 17 }
 18 int BFS()//compute a new level graph from the residual graph
 19 {
 20     int i, u, v, flag;
 21     list<int> l;//queue
 22     flag=0;
 23     for (i=1;i<=n;i++){//necessary?
 24         level[i]=INF;
 25         color[i]=0;
 26     }
 27     color[src]=1;
 28     l.push_back(src);
 29     while(!l.empty()){
 30         u=l.front();
 31         l.pop_front();
 32         for (v=0;v<=n;v++){
 33             if (map[u][v]!=0 && color[v]==0){
 34                 color[v]=1;
 35                 level[v]=level[u]+1;
 36                 l.push_back(v);
 37             }
 38         }
 39         if (u==sink)
 40             flag=1;
 41         color[u]=2;
 42     }
 43     return flag;
 44 }
 45 int Dinic()
 46 {
 47     int maxflow, u, v, resflow, last;
 48     list<int> path;//stack
 49     list<int>::iterator it;
 50     maxflow=0;
 51     while(BFS()){
 52         path.clear();
 53         path.push_back(src);
 54         while (OutDegree(src)>0){
 55             u=path.back();
 56             //search the path from s to t in level graph
 57             if (u!=sink){
 58                 if ((v=OutDegree(u))!=0)
 59                     path.push_back(v);
 60                 else{
 61                     path.pop_back();
 62                     level[u]=INF;
 63                 }
 64             }
 65             //update the residual graph along path
 66             else{
 67                 resflow=INF;
 68                 for (it=path.begin();it!=path.end();it++){
 69                     u=*it;
 70                     if ((++it)==path.end())
 71                         break;
 72                     v=*it;
 73                     if (map[u][v]<resflow)
 74                         resflow=map[u][v];
 75                     --it;
 76                 }
 77                 last=-1;
 78                 maxflow+=resflow;
 79                 for (it=path.begin();it!=path.end();it++){
 80                     u=*it;
 81                     if ((++it)==path.end())
 82                         break;
 83                     v=*it;
 84                     map[u][v]-=resflow;
 85                     map[v][u]+=resflow;
 86                     if (map[u][v]==0 && last==-1)//label the last vertex reachable from s
 87                         last=u;
 88                     --it;
 89                 }
 90                 while (path.back()!=last)
 91                     path.pop_back();
 92             }
 93         }
 94     }
 95     return maxflow;
 96 }
 97 int main(int argc, char *argv[])
 98 {
 99     int i, u, v, w, Con;
100     char c;
101     //freopen("input.txt", "r", stdin);
102     src=0;
103     while (cin>>n>>np>>nc>>m){
104         memset(map, 0sizeof(map));
105         for (i=0;i<m;i++){
106             while (c=getchar()!='(');
107             cin>>u;
108             getchar();
109             cin>>v;
110             getchar();
111             cin>>w;
112             map[u+1][v+1]=w;
113         }
114         sink=n+1;
115         n+=2;                //add the src and sink
116         m+=(np+nc);            //add new edges
117         for (i=0;i<np;i++){
118             while (c=getchar()!='(');
119             cin>>u;
120             getchar();
121             cin>>w;
122             map[src][u+1]=w;
123         }
124         for (i=0;i<nc;i++){
125             while (c=getchar()!='(');
126             cin>>u;
127             getchar();
128             cin>>w;
129             map[u+1][sink]=w;
130         }
131         Con=Dinic();
132         cout<<Con<<endl;
133     }
134     return 0;
135 }

 END

 

 

 

转载于:https://www.cnblogs.com/zen_chou/archive/2009/07/14/1523667.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值