noip2010T3关押罪犯

【问题描述】

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

在详细考察了N名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。那么,应如何分配罪犯,才能使Z市长看到的那个冲突事件的影响力最小?这个最小值是多少?

【输入】

输入文件名为prison.in。输入文件的每行中两个数之间用一个空格隔开。

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

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

【输出】

输出文件prison.out共1行,为Z市长看到的那个冲突事件的影响力。如果本年内监狱中未发生任何冲突事件,请输出0。

【输入样例】

4 6
1 4 2534
2 3 3512
1 2 28351
1 3 6618
2 4 1805
3 4 12884
【输出样例】

3512

这道题可以用二分图染色做,但用并查集会更简单;

本题要求发生的冲突事件最大影响值最小,所以我们可以采取贪心策略:

选尽量大冲突值的一对罪犯,将他们分开;

证明:设当前冲突值为v[i],比其小的第一个冲突值为v[i+1];

若选第i对罪犯分开,则最大值为v[i+1];

若选第i+1对罪犯分开,则最大值为v[i]

又因v[i]>v[i+1]

所以选较大的比选较小的更优;

我们,将冲突值从大到小排序令第i+n个点为该点的敌人,若要分开一对罪犯,则将其敌人合并,

若要被分开得一对罪犯已经在同一个并查集中,则他们只能被分在同一个监狱中,则当前冲突值就是最大的冲突值;

代码如下


  
  
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. using namespace std;
  5. const int MAX=100000+10;
  6. struct Edge{
  7. int t,v,f;
  8. }A[MAX];
  9. bool cmp(Edge a,Edge b){
  10. return a.v<b.v;
  11. }
  12. int fa[MAX*2];
  13. inline int find(int x){
  14. if(x==fa[x])
  15. return x;
  16. return fa[x]=find(fa[x]);
  17. }
  18. int main(){
  19. freopen("prison.in","r",stdin);
  20. freopen("prison.out","w",stdout);
  21. int n,m;
  22. scanf("%d %d",&n,&m);
  23. for(int i=1;i<=m;i++){
  24. scanf("%d %d %d",&A[i].f,&A[i].t,&A[i].v);
  25. }
  26. sort(A+1,A+m+1,cmp);
  27. for(int i=1;i<=n*2;i++)
  28. fa[i]=i;
  29. for(int i=m;i>=1;i--){
  30. int ff=find(A[i].f),ft=find(A[i].t);
  31. if(ff==ft){
  32. printf("%d\n",A[i].v);
  33. return 0;
  34. }
  35. fa[find(ff+n)]=find(ft);
  36. fa[find(ft+n)]=find(ff);
  37. }
  38. printf("%d\n",0);
  39. return 0;
  40. }

<think>好的,我现在需要回答用户关于NOIP2024第三题的题解请求。首先,我得明确用户的问题是什么。NOIP是全国青少年信息学奥林匹克联赛,2024年的题目目前还没有发布,所以用户可能指的是某个模拟题或者往年的题目,或者是笔误。我需要先确认这一点。 首先,我应该检查是否存在NOIP2024的题目。由于现在是2023年,2024年的比赛还没进行,所以题目不可能已经公开。用户可能是指NOIP2023的第三题,或者可能是其他比赛的题目。也有可能用户提到的题目是某个模拟赛或者训练题中的T3。 接下来,我应该考虑如何处理这种情况。如果用户确实想询问一个尚未存在的题目,我需要礼貌地指出这一点,并建议可能的解释。同时,为了帮助用户,我可以提供一般性的题解思路,或者假设题目类型并给出常见问题的解决方法。 假设用户可能混淆了年份,比如NOIP2023的T3,或者某个省份的省选题。或者用户可能在参加训练,遇到了一道题称为NOIP2024T3的模拟题。这时候,我需要引导用户提供更多信息,或者给出常见题型的解题方法。 另外,用户可能需要的是如何应对类似NOIP中的动态规划、图论、数据结构等常见问题。第三题通常难度较高,可能涉及较复杂的算法。比如,可能是树形DP、线段树、最短路算法变种、状态压缩等。 由于没有具体的题目内容,我需要给出一个通用的解题框架,帮助用户在面对类似问题时如何分析。例如,分步骤解决问题的方法:理解题意、分析输入输出、设计算法、编写代码等步骤。 同时,我可以举一个例子,假设题目是某个经典问题的变种,比如动态规划中的背包问题,或者图论中的最短路径问题,并给出相应的解题思路和代码结构。这样即使用户的问题不明确,也能从中获得有用的信息。 另外,我需要提醒用户在遇到具体题目时,应该注意的关键点,比如数据范围、时间限制、空间限制,这些因素会影响算法的选择。例如,数据量较小时可以用暴力法,而数据量大时需要更高效的算法。 最后,确保我的回答清晰、有条理,并且符合用户的需求。如果用户能提供更多题目细节,我可以给出更精确的解答。但现在的情况下,给出一般性的建议和解题策略是比较合适的。</think>由于NOIP2024尚未举办(当前为2023年),其题目自然不存在。若您指的是某次模拟赛或特定训练题,请补充以下信息以便提供更精准的题解: 1. **题目描述**(关键条件、输入输出格式) 2. **数据范围**(变量数值规模) 3. **示例输入输出** 以下提供通用高阶题型的解题框架供参考: --- ### 典型NOIP-T3级难题解题思路 以**树形动态规划+状态压缩**类问题为例: #### 问题特征 - 给定带权树结构(节点数 $n \leq 1e5$) - 要求选择若干节点满足特定约束(如不相邻) - 目标函数最优化(最大权值和) #### 解题步骤 1. **状态定义** 设 $dp[u][0/1]$ 表示以节点 $u$ 为根的子树,选/不选 $u` 时的最大权值 2. **转移方程** - 不选当前节点:$dp[u][0] += \sum \max(dp[v][0], dp[v][1])$ - 选择当前节点:$dp[u][1] += \sum dp[v][0]$ 3. **复杂度优化** 采用后序遍历实现 $O(n)$ 时间复杂度 #### 代码框架 ```cpp #include <vector> using namespace std; struct Node { int val; vector<int> children; }; pair<int, int> dfs(Node& node, vector<Node>& tree) { int select = node.val, not_select = 0; for (int child : node.children) { auto [c_not, c_sel] = dfs(tree[child], tree); select += c_not; not_select += max(c_not, c_sel); } return {not_select, select}; } int main() { // 构建树结构 // auto [final_not, final_sel] = dfs(root); // cout << max(final_not, final_sel) << endl; } ``` --- 如需具体题目解析,请提供完整题目描述。建议练习方向: 1. 动态规划(状态机模型) 2. 图论算法(网络流、差分约束) 3. 高级数据结构(线段树合并)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值