NOIP - 关押罪犯

2024-02-27 01:08
文章标签 noip 关押 罪犯

本文主要是介绍NOIP - 关押罪犯,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

描述 DescriptionS 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多。如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件。每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S 城Z 市长那里。公务繁忙的Z 市长只会去看列表中的第一个事件的影响力,如果影响很坏,他就会考虑撤换警察局长。在详细考察了N 名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。那么,应如何分配罪犯,才能使Z 市长看到的那个冲突事件的影响力最小?这个最小值是多少?输入格式 Input Format输入文件的每行中两个数之间用一个空格隔开。第一行为两个正整数N 和M,分别表示罪犯的数目以及存在仇恨的罪犯对数。接下来的M 行每行为三个正整数aj,bj,cj,表示aj 号和bj 号罪犯之间存在仇恨,其怨气值为cj。数据保证1<=aj<bj<N,0<cj<=1,000,000,000 且每对罪犯组合只出现一次。输出格式 Output Format输出共1 行,为Z 市长看到的那个冲突事件的影响力。如果本年内监狱中未发生任何冲突事件,请输出0。数据范围对于30%的数据有N≤15。对于70%的数据有N≤2000,M≤50000。对于100%的数据有N≤20000,M≤100000。
这是一道并查集的问题。可想到按照从大到小排序,然后依次处理,一旦遇到矛盾,那便是最大的矛盾。
#include <cstdio>
#include <algorithm>
using namespace std;
struct edge
{
int x, y;
int value;
};
edge prison[100000 + 5];
int pre[20000 + 5];
int ensure[2000 + 5];
int m, n;
bool cmp(edge a, edge b)
{
return a.value > b.value;
}
int FindFather(int x)
{
int r = x;
while (r != pre[r])  ///找到根节点
r = pre[r];
int i = x;
int j;
while (i != r)  ///进行路径压缩
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
void Mix(int a, int b)  ///合并
{
int fx = FindFather(a);
int fy = FindFather(b);
if (fx != fy)
pre[fy] = fx;
}
int main()
{
int xx, yy;
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; ++i)
scanf("%d%d%d", &prison[i].x, &prison[i].y, &prison[i].value);
sort(prison + 1, prison + m+1, cmp);    ///从大到小排序
for (int i = 1; i <= n; ++i)    ///初始化
{
pre[i] = i;
ensure[i] = 0;
}
for (int i = 1; i <= m; ++i)
{
xx = prison[i].x;
yy = prison[i].y;
int fx = FindFather(xx);
int fy = FindFather(yy);
if (fx == fy)   ///一旦遇到矛盾就输出
{
printf("%d\n", prison[i].value);
return 0;
}
if (ensure[xx] == 0)    ///如果 xx 还没有矛盾对象,则设置矛盾对象
ensure[xx] = yy;
else    ///如果有矛盾对象,把 yy 和矛盾对象合并
Mix(yy, ensure[xx]);
if (ensure[yy] == 0)    ///同上
ensure[yy] = xx;
else    ///同上
Mix(xx, ensure[yy]);
}
printf("0\n");
return 0;
}
在网上还碰见了40行AC的大牛,贴一下代码表示崇敬。
#include <algorithm>
#include <iostream>
using namespace std;
int n,m,f[40001],x,y;
struct data
{
int a,b,c;
}e[100001];
int gz(const data &a,const data &b)
{if(a.c>b.c)return 1;else return 0;
}
int find(int x) 
{return f[x]==x?x:f[x]=find(f[x]);
}
int main() 
{cin>>n>>m;for(int i=1;i<=m;i++)cin>>e[i].a>>e[i].b>>e[i].c;for(int i=1;i<=n*2;i++)f[i]=i;sort(e+1,e+m+1,gz);for(int i=1;i<=m;i++) {x=find(e[i].a);y=find(e[i].b);if(x==y) {cout<<e[i].c;return 0;}f[y] = find(e[i].a + n);f[x] = find(e[i].b + n);}cout<<0;return 0;
}

出处:http://hzwer.com/599.html

这篇关于NOIP - 关押罪犯的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/750734

相关文章

NOIP 2015 CCF (CSP -J)初赛真题

第二十 一届全国青少年信息学奥林匹克联赛初赛 ; 普及组C++ 语言试题 竞 赛 时 间: 20 1 5 年 1 0 月 1 1 日 1 4 : 3 0~ 1 6 : 3 0 选 手注 意: • 试腰紙共有7 页,答題紙共有2页,满分100 分。请在答感統上炸答,写在試感纸上的一律无 效。 • 不得使用任何电子设 备(如计算器、手机、 电子词典等》或查阅 任何书籍發 料。 一、单项选择题(

NOIP 2010 乌龟棋

题目 描述 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数)。棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。 乌龟棋中M张爬行卡片,分成4种不同的类型(M张卡片中不一定包含所有4种类型的卡片,见样例),每种类型的卡片上分别标有1、2、3、4四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行

NOIP2010 关押罪犯 (二分答案+二分图染色)

题意:有两个监狱,N个犯人,M对关系,每对关系描述一对犯人如果在一个监狱将会产生一个冲突值。任意安排犯人的分配,使得产生的最大冲突值最小。 题解:最大值最小,先考虑二分。二分中最重要的环节就是判定猜测值可行性以及保证答案单调性。可行性判定:对于一个猜测的最大冲突值,判定时就要保证所有大于这个冲突值的两个人不能在一个监狱。只需要将需要满足不在同一监狱的两个人连上边,如果最后可以染成二分图,就存在分

【noip】HankSon的趣味题

描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现 在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。 今天在课堂上,老师讲解了如何求两个正整数 c1和 c2 的最大公约数和最小公倍数。现 在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公 倍数”之类问题的“逆问题” ,这个问题

【noip】开车旅行 平衡树 倍增 treap tree

noip2012年day1最后一题 感觉2012年的都好难写 疫情控制也是。。 描述 小A和小B决定利用假期外出旅行,他们将想去的城市从1到N编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市i 的海拔高度为Hi,城市i 和城市j 之间的距离d[i,j]恰好是这两个城市海拔高度之差的绝对值,即d[i,j] = |Hi - Hj|。 旅行过程中,小A和小B轮

【noip】国王游戏 贪心 高精度

说实话我一开始是不想发这道题的,虽然比较水,但不知道是不是因为我太久都没有写高精度了,还是写错了,才40分,还是发上来吧。 描述 恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该

【noip】解方程 秦九韶算法

解方程 描述 已知多项式方程: a0+a1x1+a2x2……+an−1xn−1+anxn=0 a_0+a_1x^1+a_2x^2……+a_{n-1}x^{n-1}+a_nx^n=0 求这个方程在[1, m]内的整数解(n 和 m 均为正整数)。 输入格式 输入共 n+2 行。 第一行包含 2 个整数 n、m,每两个整数之间用一个空格隔开。 接下来的 n+1 行每行包含一个整数,依次为

【NOIP提高组】方格取数

【NOIP提高组】方格取数 💖The Begin💖点点关注,收藏不迷路💖 设有N*N的方格图,我们将其中的某些方格填入正整数, 而其他的方格中放入0。 某人从图得左上角出发,可以向下走,也可以向右走,直到到达右下角。 在走过的路上,他取走了方格中的数。(取走后方格中数字变为0) 此人从左上角到右下角共走3次,试找出3条路径,使得取得的数总和最大。 输入: 第

【NOIP提高组】进制转换

【NOIP提高组】进制转换 💖The Begin💖点点关注,收藏不迷路💖 我们可以用这样的方式来表示一个十进制数:将每个阿拉伯数字乘以一个以该数字所处位置的(值减1)为指数,以 10 为底数的幂之和的形式。 例如, 123 可表示为 1 × 10 ^2 + 2 × 10 ^1 + 3 × 10 ^0这样的形式。与之相似的,对二进制数来说,也可表示成每个二进制数

NOIP复习篇

NOIP复习篇———枚举 ---------------------------------------------------------------------------------------------------------------- 高手的切磋不在于难题,而在于SB算法....NOIP来了,决不能犯SB错误 ------------------------