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

[bzoj1532] [POI2005]Kos-Dicing

时间:2016-06-18 23:52:23      阅读:296      评论:0      收藏:0      [点我收藏+]

标签:

  二分答案,比赛与双方选手连边跑最大匹配。。看匹配数是否等于比赛数。

  dinic大法好++

技术分享
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=10233,inf=1002333333;
 6 struct zs{
 7     int too,pre,flow;
 8 }e[maxn<<3];int tot,last[maxn<<1];
 9 int dl[maxn<<1],dis[maxn<<1],cd[maxn];
10 int i,j,k,n,m,tt,s,t;
11  
12 int ra;char rx;
13 inline int read(){
14     rx=getchar(),ra=0;
15     while(rx<0||rx>9)rx=getchar();
16     while(rx>=0&&rx<=9)ra*=10,ra+=rx-48,rx=getchar();return ra;
17 }
18  
19 inline void insert(int a,int b,int c){
20     e[++tot].too=b,e[tot].flow=c,e[tot].pre=last[a],last[a]=tot;
21     e[++tot].too=a,e[tot].flow=0,e[tot].pre=last[b],last[b]=tot;
22 }
23 bool bfs(){
24     int l=0,r=1,now,i;
25     memset(dis,255,(t+1)<<2),dl[1]=s,dis[s]=0;
26     while(l<r&&dis[t]==-1){
27         now=dl[++l];
28         for(i=last[now];i;i=e[i].pre)if(e[i].flow&&dis[e[i].too]==-1)
29             dis[e[i].too]=dis[now]+1,dl[++r]=e[i].too;
30     }
31     return dis[t]!=-1;
32 }
33 inline int min(int a,int b){return a<b?a:b;}
34 int dfs(int x,int mx){
35     if(x==t)return mx;
36     int i,used=0,w;
37     for(i=last[x];i;i=e[i].pre)if(e[i].flow&&dis[e[i].too]==dis[x]+1){
38         w=dfs(e[i].too,min(e[i].flow,mx-used));if(w){
39             e[i].flow-=w,e[i^1].flow+=w,used+=w;
40             if(used==mx)return mx;
41         }
42     }
43     dis[x]=-1;return used;
44 }
45 inline bool check(int mid){
46     register int i;int flow=0;
47     for(i=2;i<=tt;i+=2)e[i].flow=1,e[i^1].flow=0;
48     for(i=tt+1;i<=tot;i+=2)e[i].flow=mid,e[i^1].flow=0;
49     while(bfs())flow+=dfs(s,inf);
50     return flow==m;
51 }
52 int main(){
53     n=read(),m=read();
54     s=0,t=n+m+1,tot=1;
55     for(i=1;i<=m;i++)
56         j=read(),k=read(),insert(j,i+n,1),insert(k,i+n,1),cd[j]++,cd[k]++;
57     for(i=1;i<=m;i++)insert(i+n,t,1);tt=tot;
58     for(i=1;i<=n;i++)insert(s,i,0);
59     int l=(m+n-1)/n,r=0,mid;
60     for(i=1;i<=n;i++)if(cd[i]>r)r=cd[i];
61     while(l<r){
62         mid=l+r>>1;
63         if(check(mid))r=mid;else l=mid+1;
64     }
65     printf("%d\n",l);
66     return 0;
67 }
View Code

 

[bzoj1532] [POI2005]Kos-Dicing

标签:

原文地址:http://www.cnblogs.com/czllgzmzl/p/5597084.html

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