Hdu Flow Problem

View Code
  1 #include <iostream>
  2 #include<cstdio>//最大流SAP
  3 #include<cstring>
  4 #include<vector>
  5 #include<queue>
  6 #include<algorithm>
  7 using namespace std;
  8 #define min(a,b) ((a)<(b))?(a):(b)
  9 #define max(a,b) ((a)>(b))?(a):(b)
 10 #define MAXN 200
 11 #define MAXM 10000+10//M取N的平方倍
 12 #define INF 0x3f3f3f3f
 13 //链式前向星
 14 struct enode
 15 {
 16     int t;
 17     int w;                //权值
 18     int c;                //流量
 19 //  int cost;
 20 //    int pre;            //前向指针
 21     int next;
 22 };
 23 struct lstar
 24 {
 25     struct enode e[MAXM];
 26     int box[MAXN],ecnt;
 27     //int etail[MAXN];        //尾部
 28     void init()
 29     {
 30         ecnt=0;
 31         memset(box,-1,sizeof(box));
 32     //    memset(etail,-1,sizeof(etail));        //初始化尾部
 33     }
 34     void addedge(int f,int t,int c)            //流量重载
 35     {
 36         e[ecnt].next=box[f];
 37         e[ecnt].t=t;
 38         e[ecnt].c=c;
 39         box[f]=ecnt++;
 40         e[ecnt].next=box[t];
 41         e[ecnt].t=f;
 42         e[ecnt].c=0;
 43         box[t]=ecnt++;
 44     }
 45 };
 46 
 47 int sap(int s,int t,lstar G,int N)//最大流问题
 48 {
 49     int gap[MAXN],lvl[MAXN],cur[MAXN],pre[MAXN];
 50     int curflow,ans=0,u,tmp,neck,i;
 51     memset(lvl,0,sizeof(lvl));
 52     memset(gap,0,sizeof(gap));
 53     memset(pre,-1,sizeof(pre));
 54     for(i=0;i<N;i++)
 55         cur[i]=G.box[i];
 56     gap[0]=N;
 57     u=s;
 58     while(lvl[s]<N)
 59     {
 60         if(u==t)
 61         {
 62             curflow=INF;
 63             for(i=s;i!=t;i=G.e[cur[i]].t)
 64             {
 65                 if(curflow>G.e[cur[i]].c)
 66                 {
 67                     neck=i;
 68                     curflow=G.e[cur[i]].c;
 69                 }
 70             }
 71             for(i=s;i!=t;i=G.e[cur[i]].t)
 72             {
 73                 tmp=cur[i];
 74                 G.e[tmp].c-=curflow;
 75                 G.e[tmp^1].c+=curflow;
 76             }
 77             ans+=curflow;
 78             u=neck;
 79         }
 80         for(i=cur[u];i!=-1;i=G.e[i].next)
 81             if(G.e[i].c && lvl[u]==lvl[G.e[i].t]+1)
 82                 break;
 83         if(i!=-1)
 84         {
 85             cur[u]=i;
 86             pre[G.e[i].t]=u;
 87             u=G.e[i].t;
 88         }
 89         else
 90         {
 91             if(--gap[lvl[u]]==0)
 92                 break;
 93              cur[u]=G.box[u];
 94             for(tmp=N,i=G.box[u];i!=-1;i=G.e[i].next)
 95                 if(G.e[i].c)
 96                     tmp=min(tmp,lvl[G.e[i].t]);
 97             lvl[u]=tmp+1;
 98             gap[lvl[u]]++;
 99             if(u!=s)
100                 u=pre[u];
101         }
102     }
103     return ans;
104 }
105 int main()
106 {
107       int m,n,t;
108       lstar  s;
109       scanf("%d",&t);
110       int ct=1;
111         while(t--)
112         {
113             int a,b,cost;
114             cin>>n>>m;
115            // memset(map,0,sizeof(map));
116            s.init();
117            for(int i=0;i<m;i++)
118             {
119                cin>>a>>b>>cost;
120                s.addedge(a-1,b-1,cost);
121             }//参数含义:源点 汇点 网络结点数量
122             //printf("####\n");
123           /*  for(int i=1;i<=n;i++)
124             {
125                 for(int k=s.box[i];k!=-1;k=s.e[k].next)
126                 cout<<i<< " " <<s.e[k].t<< " " <<s.e[k].c<<endl;
127             }//*/
128             cout<<"Case "<<ct++<<":";
129             cout<<" "<<sap(0,n-1,s,n)<<endl;//最大流问题
130         }
131     return 0;
132 }
133 /*
134 
135 2
136 3 2
137 1 2 1
138 2 3 1
139 3 3
140 1 2 1
141 2 3 1
142 1 3 1
143 
144 Case 1: 1
145 Case 2: 2
146 
147 */

http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?pid=1002&ojid=0&cid=4456&hide=0

直接求最大流问题

转载于:https://www.cnblogs.com/someonelikeyou/archive/2013/04/18/3029743.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值