NOIP2010关押罪犯 二分+二染色

这个题一上来 没有思路,后来想没有思路就二分吧

那么我们来二分

首先,大于当前的mid值的关系,不能出现在一个集合里

(即关系形成的图是一个二分图,判定二分图可以二染色)

如果不能形成二分图,那么说明有些关系要在一个集合里,那就向上二分

否则向下二分

#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
typedef pair<int,int>pii;
const int N=2e4+5;
const int INF=0x3f3f3f3f;
int head[N],tot,n,m;
struct Edge
{
    int u,v,next;
    bool operator<(const Edge &rhs)const
    {
        return next<rhs.next;
    }
} edge[N*10],o[N*5];
void add(int u,int v)
{
    edge[tot].v=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int cur[N];
bool dfs(int u,int f)
{
    cur[u]=(cur[f]^1);
    for(int i=head[u]; ~i; i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==f||cur[v]==(cur[u]^1))continue;
        if(cur[v]==cur[u])return false;
        if(!dfs(v,u))return false;
    }
    return true;
}
bool judge(int x)
{
    Edge tmp;
    tmp.next=x;
    int pos=upper_bound(o+1,o+1+m,tmp)-o;
    if(pos>m)return true;
    memset(head,-1,sizeof(head)),tot=0;
    memset(cur,-1,sizeof(cur));
    int s;
    for(int i=pos; i<=m; ++i)
        add(o[i].u,o[i].v),add(o[i].v,o[i].u),s=o[i].u;
    for(int i=pos;i<=m;++i){
      int s=o[i].u;
      if(cur[s]!=-1)continue;
      cur[s]=0;
      if(!dfs(s,s))return false;
    }
    return 1;
}
int main()
{
    scanf("%d%d",&n,&m);
    if(m==0)
    {
        printf("0\n");
        return 0;
    }
    for(int i=1; i<=m; ++i)
        scanf("%d%d%d",&o[i].u,&o[i].v,&o[i].next);
    o[0].next=0;
    sort(o+1,o+1+m);
    int l=0,r=m;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(judge(o[mid].next))r=mid;
        else l=mid+1;
    }
    printf("%d\n",o[(l+r)>>1].next);
    return 0;
}

时间: 2024-10-29 16:08:28

NOIP2010关押罪犯 二分+二染色的相关文章

[NOIP2010]关押罪犯(二分+二分图染色)

传送门 大意:我们把图分为两部分,使得两部分中的内部边的最大权值最小. 思路:哎,拿到题的时候想了二分图染色,发现不好做,但我没有想到二分,只好最后去骗了一个30分.正确的思路是:首先我们要 去二分最大的冲突边的是哪一条(按照权值二分),因为当二分的边权增大时,连的边也就越少,连通块的数目就越多,冲突就越少,所以边权是可以二分的,在二分过后用二分图判定,如果可以染成二分图即为可行的解. 代码: #include<cstdio> #include<algorithm> #includ

noip2010(关押罪犯)

4844: Noip2010 关押罪犯 Time Limit: 4 Sec  Memory Limit: 128 MBSubmit: 18  Solved: 12[Submit][Status][Web Board] Description S城现有两座监狱,一共关押着 N名罪犯,编号分别为 1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至 积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值" (一个正整数值)来表示某两名罪犯之间 的仇恨程度,怨气值越大,则这两名罪犯之

NOIP2010关押罪犯[并查集|二分答案+二分图]

题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件. 每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S 城Z 市长那里.公务繁忙的Z 市长只会去看列表

noip2010 关押罪犯

题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极 不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨 气值"(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之 间的积怨越多.如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并 造成影响力为c 的冲突事件. 每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表, 然后上报到S 城

NOIP2010 关押罪犯(图论+二分)

考试的时候写的最大生成树,然后二分图染色,因为这样两个矛盾很大的罪犯不会被分在一个监狱里面. 然而最大生成树超时,80分. 正解为二分边权,将边权值大于mid的全部连边构图,判断是否为二分图,如果不是二分图,那么无解. 如果无解,则说明边权的限制条件太小了,因为连的边太多,不容易形成二分图:如果有解,则说明边权的限制条件太大,因为更少的边有利于形成二分图. 80分代码,最大生成树: #include<cstdio> #include<cstring> #include<alg

noip 2010 关押罪犯 (二分图染色 并茶几)

/* 二分图染色版本 两个监狱对应二部图的两部分 在给定的怨气值里二分 对于每一个Ci 进行染色判断是否合法 染色的时候 如果这条边的ci > Ci 这两个人就带分开 即染成不同的颜色 如果染色到某两个点颜色相同且怨气值>Ci 这个Ci就不合法 二分直到最后答案 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100

回档|NOIP2010 关押罪犯

描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲 突.我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.如果两名怨气值为c的罪犯被关押在同一 监狱,他们俩之间会发生摩擦,并造成影响力为c的冲突事件.每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S 城Z市长那里.公务繁忙的Z市长只会去看列表中的第一个事件

洛谷P1525关押罪犯——二分做法

题目:https://www.luogu.org/problemnew/show/P1525 二分答案,二分图染色判断是否可行. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,ct,head[20005],ans,mx,mid; bool col[20005],vis[20005]; struct N{ int to,next,w; }ed

洛谷1525关押罪犯——二分

题目:https://www.luogu.org/problemnew/show/P1525 二分答案+二分图染色. #include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; int n,m,head[20005],xnt,x,y; ll ans,l,r,z; bool vis[20005],col[20005]; struct Nod