• 洛谷P1525 关押罪犯 贪心+并查集


    题目链接:https://www.luogu.com.cn/problem/P1525

    题意是给定n个罪犯,有m个罪犯之前有怨气值,若有怨气值为c的一对罪犯放在同一个监狱会产生影响力为c的冲突。将罪犯分成两部分使得影响力最大的冲突事件最小。

    一个并查集+贪心的好方法:把怨气值按照降序排序,尽量让c大的罪犯不放在同一个监狱,直到两个罪犯必须在同一个监狱时,就输出他们的c。具体使用简单的带权并查集实现:若v[x]=0表示x和par[x]在同一个监狱,v[x]=1则不在,然后按照带权并查集的方法处理即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxm=1000+10;
     5 const int maxn=200+10;
     6 
     7 struct st{    int x,y,num;}a[maxm];
     8 int par[maxn],v[maxn];
     9 int n,m,i,j,k;
    10 
    11 bool cmp(st p,st q){
    12     return p.num>q.num;
    13 }
    14 
    15 int find(int x){ //带权并查集,v[x]=0表示x与par[x]在相同监狱 
    16     if (par[x]==x) return x;
    17     else{
    18         int p=par[x];
    19         par[x]=find(par[x]);
    20         v[x]=(v[x]+v[p])%2;
    21     }
    22     return par[x];
    23 }
    24 
    25 int main(){
    26     //freopen("luogu1525.txt","r",stdin);
    27     scanf("%d%d",&n,&m);
    28     memset(v,0,sizeof(v));
    29     for (i=1;i<=n;i++) par[i]=i;
    30     for (i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].num);
    31     sort(a+1,a+m+1,cmp);
    32     for (i=1;i<=m;i++){
    33         int xx=find(a[i].x);int yy=find(a[i].y);
    34         if (xx==yy){
    35             int t=(v[a[i].x]-v[a[i].y])%2; //*
    36             if (t==0){ //a[i].x和a[i].y在同一个监狱 
    37                 printf("%d
    ",a[i].num);
    38                 return 0;
    39             }
    40         }
    41         else {
    42             par[xx]=yy;
    43             v[xx]=(v[a[i].y]-v[a[i].x]+1)%2; //*
    44         }
    45     }
    46     printf("%d
    ",0);
    47     //fclose(stdin);
    48     return 0;
    49 }
    洛谷1525
  • 相关阅读:
    SQL优化索引
    如何减轻工作压力(一)
    奥巴马对美国影响最大的十句话
    10种职场潜规则
    Linux中的7件武器详解
    linux时间同步,ntpd、ntpdate
    Style中Position属性详解
    vsftp配置大全超完整版
    Linux 技巧:使用 screen 管理你的远程会话
    MySQL下mysql.sock丢失问题的解决
  • 原文地址:https://www.cnblogs.com/edmunds/p/12908783.html
Copyright © 2020-2023  润新知