SGU 326 最大流(竞赛问题)

题意:

http://www.nocow.cn/index.php/Translate:Sgu/326

 

题解:

抑郁,机房的“学长”上课吵死了,心烦意乱的写了这个题,一直wa,最后发现忘了特判,网络流出现负权边了。。。

明确思想,1这个人剩下的比赛都赢(包括和组外的人比的比赛,简称组外赛),与1同小组的其他人,组外赛全输,小组内部的比赛就是网络流需要分配的结果~

思路见:http://www.cnblogs.com/proverbs/archive/2013/01/07/2850366.html

 

View Code
  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cstdio>
  6 
  7 #define N 1000
  8 #define M 400000
  9 #define INF 1e9
 10 
 11 using namespace std;
 12 
 13 int head[N],to[M],next[M],len[M];
 14 int q[M],layer[N],num[N][N],a[N],b[N],sum,qsum,mx,sb[N],map[N][N];
 15 int n,S,T,cnt,cas;
 16 
 17 inline void add(int u,int v,int w)
 18 {
 19     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
 20     to[cnt]=u; len[cnt]=0; next[cnt]=head[v]; head[v]=cnt++;
 21 }
 22 
 23 inline void read()
 24 {
 25     memset(head,-1,sizeof head); cnt=0;
 26     scanf("%d",&n);
 27     int tot=0; S=0; 
 28     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
 29     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
 30     a[1]+=b[1];
 31     for(int i=1;i<=n;i++)
 32         for(int j=1;j<=n;j++)
 33         {
 34             scanf("%d",&map[i][j]);
 35             if(j<=i) continue;
 36             if(i!=1)
 37             {
 38                 num[i][j]=++tot;
 39                 add(S,num[i][j],map[i][j]);
 40                 sum+=map[i][j];
 41             }
 42         }
 43     T=tot+n+1;
 44     for(int i=2;i<=n;i++)
 45         for(int j=i+1;j<=n;j++)
 46         {
 47             add(num[i][j],i+tot,map[i][j]);
 48             add(num[i][j],j+tot,map[i][j]);
 49         }
 50     for(int i=2;i<=n;i++) add(i+tot,T,a[1]-a[i]);
 51 }
 52 
 53 inline bool bfs()
 54 {
 55     memset(layer,-1,sizeof layer);
 56     int h=1,t=2,sta;
 57     q[1]=S; layer[S]=0;
 58     while(h<t)
 59     {
 60         sta=q[h++];
 61         for(int i=head[sta];~i;i=next[i])
 62             if(len[i]>0&&layer[to[i]]<0)
 63             {
 64                 layer[to[i]]=layer[sta]+1;
 65                 q[t++]=to[i];
 66             }
 67     }
 68     return layer[T]!=-1;
 69 }
 70 
 71 inline int find(int u,int cur_flow)
 72 {
 73     if(u==T) return cur_flow;
 74     int res=0,tmp;
 75     for(int i=head[u];~i&&res<cur_flow;i=next[i])
 76         if(len[i]>0&&layer[to[i]]==layer[u]+1)
 77         {
 78             tmp=find(to[i],min(cur_flow-res,len[i]));
 79             len[i]-=tmp; len[i^1]+=tmp; res+=tmp;
 80         }
 81     if(!res) layer[u]=-1;
 82     return res;
 83 }
 84 
 85 inline void go()
 86 {
 87     for(int i=1;i<=n;i++)
 88         if(a[1]<a[i]) {puts("NO");return;}
 89     int ans=0;
 90     while(bfs()) ans+=find(S,INF);
 91     if(ans>=sum) puts("YES");
 92     else puts("NO");
 93 }
 94 
 95 int main()
 96 {
 97     read();
 98     go();
 99     return 0;
100 }

 

吐槽:SGU简直太不人性了,登陆要记住id,做一道题需要开三个页面:题目页面,提交页面,评测页面。。。

转载于:https://www.cnblogs.com/proverbs/archive/2013/01/08/2852021.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值