noip关押罪犯 并查集做法

原创 2015年07月07日 17:43:43

1069 关押罪犯 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。

用并查集表示每个犯人之间的关系,在同一个集合中则说明两人在同一个监狱,反之则不在同一个监狱。
用类似于克鲁斯卡尔的方法,先将边排序,然后按照仇恨值的大小从大到小处理。对于每一组,先看两个人能不能加入不同的集合,
如果可以,将两人加入不同的集合,如果不可以,则输出该组仇恨值。
用补集来表示两个点不在一个集合中。如a和b’在同一个集合中,则a和b不在同一个集合中,不能把b直接加入另一个集合,因为会对后面的结果产生影响。
如,3和4不在同一个集合中,但是我们现在不知道究竟是3在第一个监狱还是4在第一个监狱,所以此时用3和4‘在同一个集合中来表示3和4不在同一个集合中。

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    int a , b , c;
};
const int N = 100000 + 50;
node man[N];
int p[N];
bool cmp(node a , node b)
{
    return a.c > b.c;
}
int find(int x)
{
    return x == p[x]?x:x=find(p[x]);
}
int main(int argc, char const *argv[])
{
    int n , m;
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
        scanf("%d%d%d", &man[i].a, &man[i].b, &man[i].c);
    for (int i = 1; i <= 2*n; ++i)
    {
        p[i] = i;
    }
    sort(man , man + m , cmp);
    for (int i = 0; i < m; ++i)
    {
        int x = find(man[i].a); int y = find(man[i].b);
        if(x == y)
        {
            cout << man[i].c << endl;
            return 0;
        }
        p[x] = find(man[i].b + n);
        p[y] = find(man[i].a + n);
    }
    printf("0\n");
    return 0;
}

相关文章推荐

noip2010关押罪犯 两种方法 并查集和二分

题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极 不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨...

【NOIP2010】关押罪犯 虚点并查集

CODEVS:http://codevs.cn/problem/1069/ 题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极 ...

【NOIp模拟】【二分图or并查集】GoToandPlay

Description小松鼠终于吃撑了,她决定逃离这个地方。  我们用一张连通图来表示整个西湖的范围,每棵容小松鼠逗留的树都用 这张图上的一个点来表示。小松鼠能够通过只跳一次互相到达的两棵树用 图上的...

Codevs_P1069 关押罪犯(并查集)

题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨气...

noip2010 关押罪犯 (并查集处理二分图分配)

P1776关押罪犯 Accepted 标签:图结构 二分图NOIP提高组2010 描述 S城现有两座监狱,一共关押着N名罪犯...

NOIP2010 关押罪犯 解题报告(并查集,补集判断思想)

在线评测: http://codevs.cn/problem/1069/ 整体思路: 首先看到了题,我们的思路很简单,尽可能的去规避怨恨较大的案件,于是将关系按照影响坏的程度排序,并...

关押罪犯-详解-noip2010-并查集--搜索--二分图

关押罪犯 网址:https://vijos.org/p/1776 描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N。他们之间的关系自然也极不和谐。很多罪犯之间甚至积怨已久,如果客观...
  • legan
  • legan
  • 2016年10月14日 02:05
  • 995

【NOIP2010TG/codevs1069】 关押罪犯 解题报告

关押罪犯  NOIP2010TG/codevs1069钻石Diamond 题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极 ...

关于如何获取int型的最大值

c++ 关于如何获取int型的最大值
  • S_Wiper
  • S_Wiper
  • 2017年05月31日 19:31
  • 572

哈希树(HashTree)

作者 罗堃 (此文为原创,若需要引用请注明出处) 从2000年开始,作者开始研究基于TCP/IP的短信息传输技术。这种技术目前在国际上的标准被成为SMPP(Short Message ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:noip关押罪犯 并查集做法
举报原因:
原因补充:

(最多只允许输入30个字)