zoukankan      html  css  js  c++  java
  • # 「NOIP2010」关押罪犯(二分图染色+二分答案)

    「NOIP2010」关押罪犯(二分图染色+二分答案)

    洛谷 P1525

    • 描述:n个罪犯(1-N),两个罪犯之间的仇恨值为c,m对仇恨值,求怎么分配使得两件监狱的最大仇恨值最小。

    • 思路:使最大xxx最小,描述就很二分。二分一个答案x后,对仇恨值大于x的罪犯之间构成的图进行二分图染色(相邻节点不染同一种颜色,总共两种颜色),染色成功则答案可行,复杂度(O(nlogn))

    二分图染色:把每个未标记的节点标记为任意一种颜色,对其进行一次 BFS,将该节点所在的连通分支全部染色,每一次扩展把未被染色的相邻节点标记为与自身相反的颜色,如果发现扩展出去的节点的颜色与自身相同,则染色失败。

    AcCode:

    #include <bits/stdc++.h>
    using namespace std;
    #define fre freopen("C:\Users\22765\Desktop\in.txt","r",stdin);
    #define ms(a) memset((a),0,sizeof(a))
    #define re(i,a,b) for(register int (i)=(a);(i)<(b);++(i))
    #define sf(x) scanf("%d",&(x))
    #define rg register
    typedef long long LL;
    const int inf=(0x7f7f7f7f);
    const int maxn=1e5+5;
    int n;
    struct node{
    	int x,y,r;
    	bool operator < (const node& a)const{
    		return r>a.r;
    	}
    }s[maxn]; 
    vector<int> v[maxn];
    int vis[maxn];
    bool isok;
    
    //dfs() : 能否将x节点所在的连通分支染色成功 
    bool dfs(int x,int color){
    	
    	if(!isok)return 0;//该连通分支染色失败,则图无法染成二分图
    	 
    	vis[x]=color;
    	int u;
    	re(i,0,v[x].size()){
    		u=v[x][i];
    		if(vis[u]==vis[x]){
    			isok=0;return 0;	
    		}
    		
    		if(!vis[u]&&!dfs(u,3-color)){//若节点未被染色,且从该节点开始染色无法染色成功 
    			isok=0;return 0; 
    		}
    	
    	}
    	return 1;
    }
    inline bool check(int m){
    	ms(vis);isok=1;
    	re(i,1,n+1)v[i].clear();
    	
    	re(i,0,m){
    		if(s[i].r>m)//对仇恨值大于二分答案的节点建图 
    			v[s[i].x].push_back(s[i].y),v[s[i].y].push_back(s[i].x);
    		
    		else break;
    	}
    	
    	re(i,1,n+1){
    		//这里一遍dfs可能无法将全部节点染色,可能有多个连通分支,所以遍历每个点 
    		if(!vis[i]&&!dfs(i,1))return 0;
    	}
    	return 1;
    }
    int main(){
    	sf(n);
    	int m;sf(m);
    	re(i,0,m)scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].r);
    	sort(s,s+m);//排序预处理便于后面建图 
    //	cout<<s[0].r<<endl;
    	int l=0,r=s[0].r,mid;
    	while(l<r){
    		mid=l+(r-l)/2;
    		if(check(mid))r=mid;
    		else l=mid+1;
    	}
    	cout<<l<<endl;
    	return 0;
    }
    
    
  • 相关阅读:
    .Net中获取打印机的相关信息
    如何在windows server 2008上配置NLB群集
    jvm分析内存泄露
    JVM调优
    线程池工作队列饱和策略
    线程池的处理流程:
    Java的Executor框架和线程池实现原理(转)
    线程池实现原理详解:
    futer.get()(如果任务没执行完将等待)
    sql注入
  • 原文地址:https://www.cnblogs.com/sstealer/p/11289841.html
Copyright © 2011-2022 走看看