码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ】【1532】【POI2005】Kos-Dicing

时间:2015-03-15 12:23:34      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

网络流/二分法


  最大值最小……直接做不太好做的时候就可以用二分+判定来搞。

  这题我们就也可以二分最大胜场v,那么怎么来判定呢?首先我们发现:每场比赛要么A赢,要么B赢,这一点跟二分图匹配非常类似,那么我们就可以建二分图:左部是参赛队伍,右边的结点表示每场比赛,对于第 i 场比赛:两支参赛队伍连x[i]->i+n和y[i]->i+n两条边,容量为1;连接i+n->T容量为1。对于第 j 支队伍,我们连S->j 容量为二分的最大胜场v。判定方法就是跑最大流,如果每场比赛都能分配出一个胜者(最大流=m)则当前v可行。

技术分享
  1 /**************************************************************
  2     Problem: 1532
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:812 ms
  7     Memory:2976 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 1532
 11 #include<vector>
 12 #include<cstdio>
 13 #include<cstring>
 14 #include<cstdlib>
 15 #include<iostream>
 16 #include<algorithm>
 17 #define rep(i,n) for(int i=0;i<n;++i)
 18 #define F(i,j,n) for(int i=j;i<=n;++i)
 19 #define D(i,j,n) for(int i=j;i>=n;--i)
 20 #define pb push_back
 21 using namespace std;
 22 inline int getint(){
 23     int v=0,sign=1; char ch=getchar();
 24     while(ch<0||ch>9){ if (ch==-) sign=-1; ch=getchar();}
 25     while(ch>=0&&ch<=9){ v=v*10+ch-0; ch=getchar();}
 26     return v*sign;
 27 }
 28 const int N=20100,M=100010,INF=~0u>>2;
 29 typedef long long LL;
 30 /******************tamplate*********************/
 31 int n,m,tot,ans,x[N],y[N];
 32 struct edge{int to,v;};
 33 struct Net{
 34     edge E[M];
 35     int head[N],next[M],cnt;
 36     void ins(int x,int y,int v){
 37         E[++cnt]=(edge){y,v};
 38         next[cnt]=head[x]; head[x]=cnt;
 39     }
 40     void add(int x,int y,int v){
 41         ins(x,y,v); ins(y,x,0);
 42     }
 43     int s,t,cur[N],d[N],Q[N];
 44     bool mklevel(){
 45         memset(d,-1,sizeof d);
 46         d[s]=0;
 47         int l=0,r=-1;
 48         Q[++r]=s;
 49         while(l<=r){
 50             int x=Q[l++];
 51             for(int i=head[x];i;i=next[i])
 52                 if (d[E[i].to]==-1 && E[i].v){
 53                     d[E[i].to]=d[x]+1;
 54                     Q[++r]=E[i].to;
 55                 }
 56         }
 57         return d[t]!=-1;
 58     }
 59     int dfs(int x,int a){
 60         if (x==t) return a;
 61         int flow=0;
 62         for(int &i=cur[x];i && flow<a;i=next[i])
 63             if (E[i].v && d[E[i].to]==d[x]+1){
 64                 int f=dfs(E[i].to,min(a-flow,E[i].v));
 65                 E[i].v-=f;
 66                 E[i^1].v+=f;
 67                 flow+=f;
 68             }
 69         if (!flow) d[x]=-1;
 70         return flow;
 71     }
 72     void Dinic(){
 73         while(mklevel()){
 74             F(i,s,t) cur[i]=head[i];
 75             ans+=dfs(s,INF);
 76         }
 77     }
 78     void build(int v){
 79         cnt=1;ans=0;
 80         memset(head,0,sizeof head);
 81         F(i,1,n) add(s,i,v);
 82         F(i,1,m){
 83             add(i+n,t,1);
 84             add(x[i],i+n,1);
 85             add(y[i],i+n,1);
 86         }
 87     }
 88 }G1;
 89 int main(){
 90 #ifndef ONLINE_JUDGE
 91     freopen("1532.in","r",stdin);
 92     freopen("1532.out","w",stdout);
 93 #endif
 94     n=getint();m=getint();
 95     G1.s=0;G1.t=n+m+1;
 96     F(i,1,m) x[i]=getint(),y[i]=getint();
 97     int l=1,r=m;
 98     while(l<=r){
 99         int mid=l+r>>1;
100         G1.build(mid);
101         G1.Dinic();
102         if (ans==m) r=mid-1;
103         else l=mid+1;
104     }
105     printf("%d\n",l);
106     return 0;
107 }
View Code

 

【BZOJ】【1532】【POI2005】Kos-Dicing

标签:

原文地址:http://www.cnblogs.com/Tunix/p/4338948.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!