zoukankan      html  css  js  c++  java
  • 洛谷 P1525 关押罪犯

    题目传送门

    解题思路:

    本题为加权并查集,首先看题,很容易想到的一个贪心策略就是尽可能把较大的分开。我们边权从大到小排序,尽可能把危害大的两个罪犯分开,再将敌人的敌人和自己合并。直到发现有一对有冲突的罪犯不可避免的被分到了一起,就输出冲突值,即为答案。如果一直到最后都没有冲突,输出0.

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 
     7 struct kkk {
     8     int a,b,c;
     9 }e[100001];
    10 int n,m,fa[20001],vis[20001];
    11 
    12 bool cmp(kkk a1,kkk b1) {
    13     return a1.c > b1.c;
    14 }
    15 
    16 int find(int x) {
    17     if(fa[x] == x) return x;
    18     return fa[x] = find(fa[x]);
    19 }
    20 
    21 bool check(int x,int y) {
    22     int x1 = find(x);
    23     int y1 = find(y);
    24     if(x1 == y1) return true;
    25     return false;
    26 }
    27 
    28 void merge(int x,int y) {
    29     x = find(fa[x]);
    30     y = find(fa[y]);
    31     fa[x] = y;
    32 }
    33 
    34 int main() {
    35     scanf("%d%d",&n,&m);
    36     for(int i = 1;i <= n; i++)
    37         fa[i] = i;
    38     for(int i = 1;i <= m; i++) 
    39         scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c);
    40     sort(e+1,e+1+m,cmp);
    41     for(int i = 1;i <= m; i++) {
    42         if(check(e[i].a,e[i].b)) {//不可避免的分到了一起 
    43             printf("%d",e[i].c);
    44             return 0;
    45         }
    46         if(!vis[e[i].a]) vis[e[i].a] = e[i].b;//标记敌人 
    47         else merge(vis[e[i].a],e[i].b);//将敌人的敌人与自己合并 
    48         if(!vis[e[i].b]) vis[e[i].b] = e[i].a;
    49         else merge(vis[e[i].b],e[i].a);
    50     }
    51     cout << 0;
    52     return 0;
    53 }

    //NOIP提高 2010 T3

  • 相关阅读:
    使用扩展运算符实现数组,对象的深拷贝
    将图片文件转成BASE64格式
    怎么让input默认为0
    两次取反的意义
    css世界一
    Q&H
    .gitignore 中添加.vscode 无效
    百度小程序
    定位元素和opacity
    js 设置元素样式
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/11242900.html
Copyright © 2011-2022 走看看