P1525 imprisoned criminals · disjoint-set / binary + bipartite graph

answer

Version 1: disjoint-set - the saying goes, the enemy's enemy is my friend
through all conflicts, if the parties to the conflict not in the same prison (not in the same prison conditions: a collection of its ancestors fa [i] is not the same), the party will go into the prison where the other enemies, using the disjoint-set, the same prison merged,
as to how to traverse, greedy ah!

Version 2: binary + bipartite graph
smallest maximum conflict influence - - First-half monotonous think the answer to
two prisons - - bipartite graph, determine eligibility, in order to prevent MLE, bipartite graph form using bfs


Here Insert Picture DescriptionHere Insert Picture Description


Disjoint-set

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m;
struct edge{
    int u,v,w;
    void init(){
        cin>>u>>v>>w;
    }
}e[N];
bool cmp(edge x,edge y){return x.w>y.w;}
int fa[N];//将同盟者归为一类
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
bool judge(int u,int v){return find(u)==find(v);}
void join(int u,int v){
    u=find(u);v=find(v);
    fa[u]=v;
}
int enemy[N];//敌人
int main(){
    cin>>n>>m;
    for (int i = 1; i <= n; ++i) fa[i]=i;
    for (int i = 1; i <= m; ++i) e[i].init();
    sort(e+1,e+1+m,cmp);//从大到小排列 贪心
    
    for (int i = 1; i <= m; ++i) {
        int u=e[i].u;
        int v=e[i].v;
        if(judge(u,v)){//如果在同一个集合内
            return printf("%d", e[i].w),0;
        }else{
            if(!enemy[u]) enemy[u]=v;
            else join(enemy[u],v);//合并敌人

            if(!enemy[v]) enemy[v]=u;
            else join(enemy[v],u);
        }
    }
    puts("0");//当没有冲突时 输出0
    return 0;
}

+ Binary bipartite graph (BFS)

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m;
struct edge{
    int next,to,w;
}e[N];
int head[N],tot=0;
int color[N];
void add(int u,int v,int w){
    e[++tot].to=v;
    e[tot].w=w;
    e[tot].next=head[u];
    head[u]=tot;
}
bool check(int ans){
    queue<int>q;
    memset(color, 0, sizeof(color));//每次判断都要清空
    for (int i = 1; i <= n; ++i) {
        if(!color[i]){
            q.push(i);
            color[i]=1;
            while(q.size()){
                int u=q.front();
                q.pop();
                for (int j = head[u]; j; j=e[j].next) {
                    if(e[j].w>ans){//冲突影响力值大于答案 说明要分图
                        int v=e[j].to;
                        if(!color[v]){//如果没有染过色
                            color[v]=3-color[u];
                            q.push(v);
                        }else if(color[v]==color[u])return false;
                    }
                }
            }
        }
    }
    return true;
}
int main(){

    int r=0;
    cin>>n>>m;
    for (int i = 1,u,v,w; i <= m; ++i) {
        cin>>u>>v>>w;
        add(u,v,w);
        add(v,u,w);
        r=max(r,w);//二分边界
    }
    
    int l=0,mid;
    while(l<r){
        mid=(l+r)/2;
        if(check(mid)){
            r=mid;
        }else l=mid+1;
    }
    printf("%d",r);
    return 0;
}
Published 43 original articles · won praise 0 · Views 1251

Guess you like

Origin blog.csdn.net/Yubing792289314/article/details/104138072