关押罪犯

题目:
https://ac.nowcoder.com/acm/problem/16591

思路一:

用贪心

首先通过冲突从大到小排序

通过扩展域并查集尽可能的把冲突大的分别分到两个不同的监狱,直到要分的两个已经在一个集合,那就得到最大值最小的那个了

遍历的时候清醒一点,不要把n,m搞混了

#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=4e4+7;
const int mm=1e5+7;
int f[maxn];
int find(int x)
{
    return x==f[x]?x:f[x]=find(f[x]);
}
struct pri
{
   int a,b,c;
};
struct pri p[mm];
int cmp(pri q,pri w)
{
    return q.c>w.c;
}
 void merge(int x,int y)
 {
     int fx=find(x);
     int fy=find(y);
     
     f[fx]=fy;
 }
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=2*n;i++)
        f[i]=i;
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&p[i].a,&p[i].b,&p[i].c);
    }
    sort(p+1,p+m+1,cmp);
    int i;
    int flag=0;
    for(i=1;i<=m;i++)
    {
        int x=p[i].a;
        int y=p[i].b;
        if(find(x)==find(y))
        {
            printf("%d\n",p[i].c);
            flag=1;
           break;
        }
        merge(x,y+n);
        merge(x+n,y);
    }
    if(flag==0)
    printf("0\n");
    return 0;
}

 

 

思路二:用二分加染色

(ps:一定要分清楚n,m,maxn,maxm,我容易写着写着就混了)

二分来check(middle)

check的时候,如果小于mid是可以不管的,注意每次Check要初始化,而且大于Mid的要连边;

dfs,没染色 的时候是-1,有边的两个点必须是不同颜色的,如果碰到连边的两个点都染色了且不同return 0;

特判0

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e4+7;
const int maxm=1e5+7;
int n,m,l,r,mid;
int col[maxn];
vector<int> q[maxn];
struct edge
{
    int u,v,w;
}e[maxm];
int cmp(edge a,edge b)
{
    return a.w>b.w;
}
int dfs(int x)
{
    for(int i=0;i<q[x].size();i++)
    {
        int t=q[x][i];
        if(col[t]==-1)
        {
            col[t]=col[x]^1;
            if(dfs(t)==0)
                return 0;
        }
        else if(col[t]!=(col[x]^1))
            return 0;
    }
    return 1;
}
int check(int x)
{
    for(int i=1;i<=n;i++)
    {
        q[i].clear();
        col[i]=-1;
    }
    for(int i=1;i<=m;i++)
    {
        if(e[i].w<x)
            break;
        int x=e[i].u;
        int y=e[i].v;
        q[x].push_back(y);
        q[y].push_back(x);
    }
    for(int i=1;i<=n;i++)
    {
        if(col[i]==-1)
        {
            col[i]=2;
            if(dfs(i)==0)
                return 0;
        }
    }
    return 1;
}
int main()
{scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
    scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
sort(e+1,e+m+1,cmp);
l=0,r=1e9;
if(check(0))
    printf("0");
else
{
    while(l<=r)
{
    mid=(l+r)/2;
    if(check(mid))
        r=mid-1;
    else
        l=mid+1;
}
    printf("%d\n",r);
}

}

 

posted @ 2021-06-10 21:33  废柴废柴少女  阅读(100)  评论(0)    收藏  举报