# "NOIP2010" imprisoned criminals (bipartite graph + half staining answer)

"NOIP2010" imprisoned criminals (bipartite graph + half staining answer)

Luo Gu P1525

  • Description: n criminals (1-N), hatred between two criminals value c, m hatred value, find how to minimize the maximum allocation Hate two prisons.

  • Ideas: the largest xxx minimum, describe very dichotomy. Half an answer xlater, is greater than hatred xFIG configuration of criminals between the bipartite graph coloring (dye neighboring node is not the same color, two colors in total), the answer staining successfully feasible complexity \ (O (nlogn) \) .

    Bipartite graph coloring: The unmarked marking each node is any one color, the BFS them once, all of the branch node where the communication staining, extended to every neighboring node undyed itself marked contrast color, if you find out the color of the expansion of the self-same node, then stain fail.

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;
}

Guess you like

Origin www.cnblogs.com/sstealer/p/11289841.html