您的位置:首页 > 其它

noip2010 关押罪犯 二分答案+二分图判断

2016-10-07 13:14 288 查看
之前写过一个用虚点并查集做的,今天终于用二分ac了。

大体思路:

二分答案,小于mid的边忽略不计,如果不能构成二分图就要往大找让l=mid,如果可以就r=mid。

判断二分图要注意每次初始化color,可以用0和1也可以用1和2表示。从1到n循环,如果没有标记的就开始深搜,每次深搜把所有邻边染色。

其实还是参考了很多别人的代码...

一开始搞不明白标记的问题,后来终于想通,求最小值,如果ok的话要往下找,也就是r=mid,之前一直没转过弯来。

不知道为什么好多人每次二分都要重新构图,直接判断一下不就可以了吗?
http://blog.csdn.net/moon_sky1999/article/details/52744564?locationNum=2
这一篇还很好理解,只不过一层一层地往下堆代码有点吓人,在这个的基础上改了个dfs,下面贴代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=2e4+1;
const int inf=1e9;
int mid;
bool ok;
struct node{int t,w;};
vector<node> a[maxn];
int color[maxn]={0};
bool inq[maxn]={0};
void dfs(int x)
{
if(ok==0)
return;
for(int j=0;j<a[x].size();j++)
{
int w=a[x][j].w;
int t=a[x][j].t;
if(w<=mid) continue;
if(color[t]==0)
{
color[t]=3-color[x];
dfs(t);
}
else if(color[t]==color[x])
{
ok=0;
return;

}
}
}
int main()
{
ios::sync_with_stdio(false);
int n,m;cin>>n>>m;
int r=-inf,l=inf;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
node e;e.w=z;
e.t=y;a[x].push_back(e);
e.t=x;a[y].push_back(e);
l=min(z,l);
r=max(r,z);
}
if(l==r)l=0;
while(l<r)
{
mid=(l+r)/2;
memset(color,0,sizeof(color));
memset(inq,0,sizeof(inq));
ok=1;
for(int i=1;i<=n;i++)
{
if(color[i]==0)
{
color[i]=1;
dfs(i);
}
if(ok==0)
break;
}
if(ok)r=mid;
else l=mid+1;
}
cout<<l;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息