您的位置:首页 > 理论基础 > 计算机网络

Bzoj 1532: [POI2005]Kos-Dicing 二分,网络流

2016-03-24 23:54 507 查看

1532: [POI2005]Kos-Dicing

Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 1373 Solved: 444
[Submit][Status][Discuss]

Description

Dicing 是一个两人玩的游戏,这个游戏在Byteotia非常流行. 甚至人们专门成立了这个游戏的一个俱乐部. 俱乐部的人时常在一起玩这个游戏然后评选出玩得最好的人.现在有一个非常不走运的家伙,他想成为那个玩的最好的人,他现在知道了所有比赛的安排,他想知道,在最好的情况下,他最少只需要赢几场就可以赢得冠军,即他想知道比赛以后赢的最多的那个家伙最少会赢多少场.

Input

第一行两个整数n 和 m, 1 <= n <= 10 000, 0 <= m <= 10 000; n 表示一共有多少个参赛者, m 表示有多少场比赛. 选手从1 到 n编号. 接下来m 行每行两个整数表示该场比赛的两个选手,两个选手可能比赛多场.

Output

第一行表示赢得最多的人最少会赢多少场

Sample Input

4 4

1 2

1 3

1 4

1 2

Sample Output

1

HINT

Source

题解:
二分+网络流。
S向每场比赛连边为1,每场比赛向两个选手连边为1,每个选手向T连二分的上界cap即可。

#include<bits/stdc++.h>
using namespace std;
#define MAXN 20020
#define INF 1e9
struct node
{
int begin,end,value,next;
}edge[4*MAXN];
int cnt,Head[MAXN],S,T,dis[MAXN],q[MAXN],a[MAXN],b[MAXN],n,m,cur[MAXN];
void addedge(int bb,int ee,int vv)
{
edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void addedge1(int bb,int ee,int vv)
{
addedge(bb,ee,vv);addedge(ee,bb,vv);
}
int read()
{
int s=0,fh=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
return s*fh;
}
void Build(int cap)
{
memset(Head,-1,sizeof(Head));cnt=1;
for(int i=1;i<=m;i++){addedge1(S,n+i,1);addedge1(n+i,a[i],1);addedge1(n+i,b[i],1);}
for(int i=1;i<=n;i++)addedge1(i,T,cap);
}
int BFS()
{
int head,tail,u,v,i;
head=0;tail=1;q[tail]=S;
memset(dis,-1,sizeof(dis));dis[S]=0;
while(head!=tail)
{
head++;if(head==20010)head=0;
u=q[head];
for(i=Head[u];i!=-1;i=edge[i].next)
{
v=edge[i].end;
if(edge[i].value>0&&dis[v]<0)
{
dis[v]=dis[u]+1;
tail++;if(tail==20010)tail=0;
q[tail]=v;
}
}
}
if(dis[T]<=0)return 0;
else return 1;
}
int DFS(int u,int minflow)
{
int used=0,ans=0,i,v;
if(u==T)return minflow;
for(i=Head[u];i!=-1;i=edge[i].next)
{
v=edge[i].end;
if(edge[i].value>0&&dis[v]==dis[u]+1)
{
ans=minflow-used;
ans=DFS(v,min(ans,edge[i].value));
edge[i].value-=ans;
edge[i^1].value+=ans;
used+=ans;
if(used==minflow)return minflow;
}
}
if(used==0)dis[u]=-1;
return used;
}
int Dinic()
{
int maxflow=0,ans=0,i;
while(BFS()){for(i=1;i<=T;i++)cur[i]=Head[i];ans=DFS(S,INF);if(ans==0)break;maxflow+=ans;}
return maxflow;
}
int main()
{
int i,l,r,mid,k,ans=0;
n=read();m=read();
S=n+m+1;T=S+1;
//memset(Head,-1,sizeof(Head));cnt=1;
for(i=1;i<=m;i++)
{
//addedge1(S,n+i,1);
a[i]=read();b[i]=read();
//addedge1(n+i,a,INF);
//addedge1(n+i,b,INF);
}
//cntcnt=cnt;
l=1;r=m;
while(l<=r)
{
mid=(l+r)/2;
Build(mid);
k=Dinic();
if(k>=m){ans=mid;r=mid-1;}
else l=mid+1;
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: