zoukankan      html  css  js  c++  java
  • P1525 关押罪犯 题解

    Link

    P1525 关押罪犯

    Solve

    此题有并查集和二分图两种做法,我采用的是二分图

    本题的答案具有单调性,可以通过二分法,把求最值问题转化成判断问题。

    二分答案,设当前二分的值为(mid),此时在两个仇恨成都大于(mid)的罪犯都必须被安排在不同的监狱,所以在两个罪犯之间连一条边,得到一张无向图,然后判断这个无向图是否能组成二分图,若是二分图则上界(r=mid),否则令下界(l=mid+1)

    Code

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100005,maxe=200005;
    int N,M,flg,lnk[maxn],nxt[maxe],son[maxe],w[maxe],cnt,vis[maxn],max_x,ans;
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    inline void add_e(int x,int y,int z){son[++cnt]=y;w[cnt]=z;nxt[cnt]=lnk[x];lnk[x]=cnt;}
    int DFS(int x,int color,int up){
    	vis[x]=color;
    	for(int j=lnk[x];j;j=nxt[j]){
    		if(w[j]<=up)continue;
    		if(!vis[son[j]]){
    			if(!DFS(son[j],3-color,up))return 0;;
    		}
    		else if(vis[son[j]]==color)return 0;
    	}
    	return 1;
    }
    int main(){
    	freopen("P1525.in","r",stdin);
    	freopen("P1525.out","w",stdout);
    	N=read();M=read();
    	for(int i=1;i<=M;i++){
    		int x=read(),y=read(),z=read();
    		max_x=max(max_x,z);
    		add_e(x,y,z);add_e(y,x,z);
    	}
    	int L=0,R=max_x,mid;
    	while(L<=R){
    		mid=(R-L>>1)+L;flg=0;
    		memset(vis,0,sizeof vis);
    		for(int i=1;i<=N;i++){
    			if(!vis[i])if(!DFS(i,1,mid)){flg=1;break;}
    		}
    		if(flg)L=mid+1;
    		else {R=mid-1;ans=mid;};
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Java集合——Map接口
    Django 创建一个返回当前时间的页面
    python 练习 后台返回当前时间
    python 练习 simple_server 判断路径及返回函数
    通过 docker 来搭建 Jenkins
    Bitbucket 触发内网 Jenkins Build
    jQuery 扩展方法
    HTML 练习滑动
    HTML 练习淡入淡出
    HTML 练习显示隐藏
  • 原文地址:https://www.cnblogs.com/martian148/p/13912657.html
Copyright © 2011-2022 走看看