代码展示测试

hdu_4280(最大流的优化)

  

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<queue>
  4 
  5 using namespace std;
  6 
  7 #define N 100010
  8 #define M 400010
  9 #define INF 0x3f3f3f3f
 10 
 11 int from[M],to[M],next[M],cap[M],head[N],ant;
 12 
 13 void init(){ ant=0;memset(head,-1,sizeof(head));}
 14 void add(int a,int b,int c){
 15     to[ant]=b;
 16     cap[ant]=c;
 17     from[ant]=a;
 18     next[ant]=head[a];
 19     head[a]=ant++;
 20 
 21     to[ant]=a;
 22     cap[ant]=0;
 23     from[ant]=b;
 24     next[ant]=head[b];
 25     head[b]=ant++;
 26 }
 27 
 28 int dp[N],num[N];
 29 void bfs(int s,int e){
 30     int u,i;
 31     memset(num,0,sizeof(num));
 32     memset(dp,32,sizeof(dp));
 33     queue<int> que;
 34     que.push(s);dp[s]=0;num[0]=1;
 35     while(!que.empty()){
 36         u=que.front();que.pop();
 37         for(i=head[u];i!=-1;i=next[i]){
 38             if(cap[i]>0) continue;
 39             if(dp[to[i]]>dp[u]+1){
 40                 dp[to[i]]=dp[u]+1;
 41                 que.push(to[i]);
 42                 num[dp[to[i]]]++;
 43             }
 44         }
 45     }
 46 }
 47 int cur[N],pre[N];
 48 int sap(int s,int e,int n){
 49     int i,x,ans=0,inf;
 50     bfs(e,s);x=s;
 51     memcpy(cur,head,sizeof(head));
 52     while(dp[s]<n){
 53         if(x==e){
 54             inf=INF;i=e;
 55             while(i!=s){
 56                 if(cap[pre[i]]<=inf) x=from[pre[i]],inf=cap[pre[i]];
 57                 i=from[pre[i]];
 58             }
 59             ans+=inf;i=e;
 60             while(i!=s){
 61                 cap[pre[i]]-=inf;
 62                 cap[pre[i]^1]+=inf;
 63                 i=from[pre[i]];
 64             }
 65         }
 66         if(x!=e&&num[dp[x]-1]==0) break;
 67         for(i=cur[x];i!=-1;i=next[i]){
 68             if(dp[to[i]]+1==dp[x]&&cap[i]>0) break;
 69         }
 70         if(i!=-1){
 71             cur[x]=i;pre[to[i]]=i;x=to[i];
 72         }else {
 73             inf=n-1;
 74             if(--num[dp[x]]==0) break;
 75             for(i=head[x];i!=-1;i=next[i]){
 76                 if(cap[i]>0&&dp[to[i]]<inf){
 77                     inf=dp[to[i]];cur[x]=i;
 78                 }
 79             }
 80             num[dp[x]=inf+1]++;
 81             if(x!=s) x=from[pre[x]];
 82         }
 83     }
 84     return ans;
 85 }
 86 
 87 int main(){
 88     int T,cas,m,n,i,a,b,c,maxx,minx,s,e;
 89     scanf("%d",&T);
 90     for(cas=1;cas<=T;cas++){
 91         init();
 92         minx=INF;maxx=-INF;
 93         scanf("%d%d",&n,&m);
 94         for(i=1;i<=n;i++){
 95             scanf("%d%d",&a,&b);
 96             if(a<=minx) minx=a,s=i;
 97             if(a>=maxx) maxx=a,e=i;
 98         }
 99         for(i=1;i<=m;i++){
100             scanf("%d%d%d",&a,&b,&c);add(a,b,c);add(b,a,c);
101         }
102         printf("%d\n",sap(s,e,n));
103     }
104     return 0;
105 }
View Code

 

转载于:https://www.cnblogs.com/lazier/p/3309423.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值