您的位置:首页 > 其它

[bzoj1191][HNOI2006]超级英雄Hero

2017-03-14 16:22 555 查看
题意:有n个锦囊妙计,m道题。先从第1道题做起,每道题都有两个妙计可以解决,解决之后才能进入下一题,每个妙计只能用一次,求最多能解决多少题

题解:二分答案+网络流check

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define S 0
#define T 2001
using namespace std;
inline int read()
{
int  x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

queue<int> qu;
int cnt=1,n,m;
int head[2005],q[2005];
struct edge{
int to,next,w;
}e[50005];

void ins(int f,int t,int w){e[++cnt].next=head[f];head[f]=cnt;e[cnt].to=t;e[cnt].w=w;}
void insw(int f,int t,int w){ins(f,t,w);ins(t,f,0);}

int dfs(int x,int f)
{
if(x==T)return f;
int used=0;
for(int i=head[x];i;i=e[i].next)
if(e[i].w&&q[e[i].to]==q[x]+1)
{
int w=dfs(e[i].to,min(e[i].w,f-used));
used+=w;e[i].w-=w;e[i^1].w+=w;
if(f==used)return f;
}
return used;
}

bool bfs(int lim)
{
memset(q,0,sizeof(q));q[S]=1;qu.push(S);
while(!qu.empty())
{
int x=qu.front();qu.pop();
for(int i=head[x];i;i=e[i].next) if(e[i].w&&!q[e[i].to]&&(e[i].to-n<=lim||e[i].to==T))
{q[e[i].to]=q[x]+1;qu.push(e[i].to);}
}
return q[T]>0;
}

bool check(int x)
{
int ans=0;
for(int i=2;i<=cnt;i+=2) e[i].w=1,e[i^1].w=0;
while(bfs(x))ans+=dfs(S,1000000);
return ans==x;
}

int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)insw(S,i,1);
for(int i=1;i<=m;i++)insw(read()+1,i+n,1),insw(read()+1,i+n,1),insw(i+n,T,1);
int l=1,r=n,mid,ans=0;
while(l<=r)
{
mid=(l+r)>>1;if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: