1069 关押罪犯

codevs——1069 关押罪犯

洛谷——P1525 关押罪犯

2010年NOIP全国联赛提高组

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题解

题目描述 Description

S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极

不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨

气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之

间的积怨越多。如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并

造成影响力为c 的冲突事件。

每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,

然后上报到S 城Z 市长那里。公务繁忙的Z 市长只会去看列表中的第一个事件的影响力,

如果影响很坏,他就会考虑撤换警察局长。

在详细考察了N 名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在

两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只

要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。那

么,应如何分配罪犯,才能使Z 市长看到的那个冲突事件的影响力最小?这个最小值是少?

输入描述 Input Description

第一行为两个正整数N 和M,分别表示罪犯的数目以及存在仇恨的罪犯对数。

接下来的M 行每行为三个正整数aj,bj,cj,表示aj 号和bj 号罪犯之间存在仇恨,其怨气值为cj。数据保证且每对罪犯组合只出现一次。

输出描述 Output Description

共1 行,为Z 市长看到的那个冲突事件的影响力。如果本年内监狱

中未发生任何冲突事件,请输出0。

样例输入 Sample Input

4 6

1 4 2534

2 3 3512

1 2 28351

1 3 6618

2 4 1805

3 4 12884

样例输出 Sample Output

3512

数据范围及提示 Data Size & Hint

罪犯之间的怨气值如下面左图所示,右图所示为罪犯的分配方法,市长看到的冲突事件

影响力是3512(由2 号和3 号罪犯引发)。其他任何分法都不会比这个分法更优。

【数据范围】

对于30%的数据有N≤ 15。

对于70%的数据有N≤ 2000,M≤ 50000。

对于100%的数据有N≤ 20000,M≤ 100000。

并查集+贪心

因为就有两个监狱 两个人要么一个监狱 要么不一个监狱(废话- - )
为了使ans最小 我们一定会让ci大的组合先分开
所以按ci排一遍序 然后for每一对
如果发现他俩在一个集合 输出ci结束
否则的话 我们希望的是把他两个分开
即把他们分别跟对方的仇人合并
所以我们假设每个人的仇人都是i+n
对于i 如果另外两个人都合并到了i+n 说明两个人一定在一所监狱 

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 200001
#define maxn 99999999
using namespace std;
int n,m,fa[N>>1];
struct nn
{
    int x,y,z;
}a[N];
int find(int x)
{
    if(fa[x]==x) return fa[x];
    else  fa[x]=find(fa[x]);
}
int cmp(nn a,nn b)
{
    return a.z>b.z;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=2*n;i++)
      fa[i]=i;
    for(int i=1;i<=m;i++)
     scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    sort(a+1,a+1+m,cmp);
    for(int i=1;i<=m;i++)
    {
        int r1=find(a[i].x);
        int r2=find(a[i].y);
        if(r1==r2)
        {
            printf("%d",a[i].z);
            return 0;
        }
        fa[r1]=find(a[i].y+n);
        fa[r2]=find(a[i].x+n);
    }
    printf("0");
    return 0;
}

二分图判定

这个题的正解是二分图判定,但是好像这种做法比上述并查集+贪心跑得慢。。。。

对于这个题,我们先把有怨气的所有罪犯连一条边,表明他们不能放在同一个监狱中。

然而我们必须要把两个罪犯放在一起,对于那种跟谁都有仇的罪犯我们要找个怨气最小的和它放在一块。

但是我们要怎样找这个与她怨气最小的罪犯呢?(我们这里要处理出的是怨气总值最小)

我们先用二分的方法预处理出所能承受的最小怨气(这样快啊)

然后我们在对于这个怨气值判断它的所有与他相连的边中是否有比这个值大的,如果有,我们判断它是否可以形成一个二分图,不能,换一种放罪犯的方法。

代码:

#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100001
using namespace std;
int n,m,x,y,z,ans,tot,C,col[N],head[N<<1];
bool flag;
struct Edge
{
    int to,dis,next;
}edge[N<<1];
struct nn
{
    int x,y,z;
}a[N];
void add(int x,int y,int z)
{
    tot++;
    edge[tot].to=y;
    edge[tot].dis=z;
    edge[tot].next=head[x];
    head[x]=tot;
}
int paint(int s)
{
    for(int i=head[s];i;i=edge[i].next)
     if(edge[i].dis>C)
        {
            if(col[edge[i].to]==col[s])  return 0;
            if(col[edge[i].to]==-1)
            {
                col[edge[i].to]=col[s]^1;
                if(!paint(edge[i].to)) return 0;
            }
        }
    return 1;
}

int cmp(nn a,nn b)
{
    return a.z>b.z;
}
bool cheak()
{
    for(int i=1;i<=n;i++)   //对于我们二分出的C值挨个进行染色
      if(col[i]==-1)
      {
          col[i]=0;
          if(!paint(i)) return 0;
       }
       return 1;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
     {
         scanf("%d%d%d",&x,&y,&z);
         a[i].x=x,a[i].y=y,a[i].z=z;//主要是方便我们最后找最小值
         add(x,y,z);//我们将存在怨气的罪犯连边,表明他们在怨气值大的时候不能在一个监狱中
         add(y,x,z);
     }
     sort(a,a+1+m,cmp);//我们将怨气值从大到小排序
     int l=0,r=m;//我们利用二分找这个怨气的最小值
     while(l<=r)//我们还能进行二分
     {
         memset(col,-1,sizeof(col));
         int mid=(l+r)>>1;
         C=a[mid].z;
         if(cheak()) ans=C,l=mid+1;//这样说明这个数我们可以再将它减小
         else r=mid-1;//当前值不能将这些罪犯分开
     }
    printf("%d",ans);
    return 0;
}
时间: 2024-11-02 09:37:50

1069 关押罪犯的相关文章

贪心 + 并查集 之 CODE[VS] 1069 关押罪犯 2010年NOIP全国联赛提高组

/* 贪心 + 并查集 之 CODE[VS] 1069 关押罪犯  2010年NOIP全国联赛提高组 两座监狱,M组罪犯冲突,目标:第一个冲突事件的影响力最小. 依据冲突大小,将M组罪犯按从大到小排序,按照排序结果,依次把每组罪犯分开放入两个监狱, 直到当前这组罪犯已经在同一个监狱中了,此时即为答案. 实现: 1)通过不在同一个监狱的罪犯,推断出在同一个监狱的罪犯.(依据:一共就两个监狱)      ftr[b] = a+n   // a和b是在不同监狱 ftr[c] = a+n   // a和

codevs 1069关押罪犯

传送门 1069 关押罪犯 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamon 题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极 不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨 气值"(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之 间的积怨越多.如果两名怨气值为c 的罪犯被关押在同一监狱,他

洛谷 P1525 关押罪犯==codevs 1069 关押罪犯[NOIP 2010]

P1525 关押罪犯 513通过 1.4K提交 题目提供者该用户不存在 标签图论并查集NOIp提高组2010 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 咳咳.竟MLE了. 囧.运行时错误,错误编号-… 点2是何方神圣? 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.

codevs 1069 关押罪犯 2010年NOIP全国联赛提高组

时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极 不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨 气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之 间的积怨越多.如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并 造成影响力为c 的冲突事件. 每年年末,警察局

codevs 1069 关押罪犯 并查集

很有意思的一道题.刚开始看不出这是道并查集,后来看了题解才会做,就是把要分开的囚犯放在同个集合里,表示这两个囚犯不在同一间监狱,但不是直接合并,例如1和2要分开,则1和2’.1’和2合并(x’为x的虚点),同个集合中实点和虚点分属于两间监狱(即x’与y在不同监狱):再例如,1和2,2和3要分开,则1和2’合并,2’和3合并,那么1和3会在同一间监狱,1’和2合并,2和3’合并,那么2就在另一间监狱.这样一来整道题的思路就呼之欲出了:按仇恨值从大到小分开每对囚犯,若出现无法分开的情况(即已在同一个

NOIP2010提高组 关押罪犯 -SilverN

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

Vijos P1776关押罪犯

题目来源:https://www.vijos.org/p/1776 P1776关押罪犯 Accepted 标签:NOIP提高组2010[显示标签] 描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.如果两名怨气值为c的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c的冲

NOIP2010 提高组 洛谷P1525 关押罪犯

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

tyvj P1403 关押罪犯 题解

P1403 [NOIP2010]关押罪犯 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时 可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.如果两名怨气值为c 的罪犯 被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件.    每年