zoukankan      html  css  js  c++  java
  • 洛谷 P1525 关押罪犯(并查集|二分图判定&二分答案)

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

    解法一:并查集

    按照w排序,看每一对u、v,如果两个在同一个并查集中,那么输出w,即为最大。

    如果不在:当u还没有敌人时,则敌人为v;如果有敌人,那么u原来的敌人e[u]和现在敌人v为一个并查集。同理。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=100005;
     7 int n,m;
     8 int f[N],e[N];
     9 struct node{
    10     int u,v,w;
    11 }q[N];
    12 bool cmp(node a,node b){
    13     return a.w>b.w;
    14 }
    15 int find(int x){
    16     if(f[x]!=x) f[x]=find(f[x]);
    17     return f[x];
    18 }
    19 int main(){
    20     scanf("%d%d",&n,&m);
    21     for(int i=1;i<=m;i++)
    22         scanf("%d%d%d",&q[i].u,&q[i].v,&q[i].w);
    23     sort(q+1,q+m+1,cmp);
    24     for(int i=1;i<=n;i++) f[i]=i;
    25     for(int i=1;i<=m;i++){
    26         int u=q[i].u,v=q[i].v;
    27         int r1=find(u),r2=find(v);
    28         if(r1==r2) {printf("%d",q[i].w); return 0;}
    29         if(!e[u]) e[u]=v;
    30         else f[find(e[u])]=find(v);
    31         if(!e[v]) e[v]=u;
    32         else f[find(e[v])]=find(u);
    33     }
    34     printf("0");
    35     return 0;
    36 }
    AC代码

    解法二:二分图判定+二分答案

    因为题目求的是最大值最小,所以可以用二分答案。二分这个答案,然后将大于等于这个二分的答案的边的两边的点进行染色,看是否是二分图。(自己的二分答案写的好奇葩

    AC代码:

     1 #include<cstdio>
     2 #include<queue>
     3 #include<cstring>
     4 #include<iostream>
     5 using namespace std;
     6 const int N=100005;
     7 int n,m,tot;
     8 int head[N],color[N];
     9 struct node{
    10     int to,next,w;
    11 }edge[N<<1];
    12 void init(){
    13     memset(head,-1,sizeof(head));
    14 }
    15 void add(int u,int v,int w){
    16     edge[tot].to=v;
    17     edge[tot].next=head[u];
    18     edge[tot].w=w;
    19     head[u]=tot++;
    20 }
    21 bool work(int x){
    22     queue<int> q;
    23     memset(color,0,sizeof(color));
    24     for(int i=1;i<=n;i++){
    25         if(!color[i]){
    26             q.push(i);
    27             color[i]=1;
    28             while(!q.empty()){
    29                 int u=q.front(); q.pop();
    30                 for(int i=head[u];i!=-1;i=edge[i].next){
    31                     int v=edge[i].to;
    32                     if(edge[i].w>=x){
    33                         if(!color[v]){
    34                             q.push(v);
    35                             if(color[u]==1) color[v]=2;
    36                             else color[v]=1;
    37                         }
    38                         else if(color[v]==color[u]) return 0;
    39                     }
    40                 }
    41             }
    42         }
    43     }
    44     return 1;
    45 }
    46 int main(){
    47     init();
    48     int l=0,r=0,ans=0;
    49     scanf("%d%d",&n,&m);
    50     for(int i=1;i<=m;i++){
    51         int u,v,w;
    52         scanf("%d%d%d",&u,&v,&w);
    53         r=max(r,w);
    54         add(u,v,w); add(v,u,w);
    55     }
    56     r++;
    57     while(l<=r){
    58         int m=(l+r)>>1;
    59         if(work(m)) {ans=m; r=m-1;}
    60         else l=m+1;
    61     }
    62     if(ans==0) {printf("0"); return 0;}
    63     else printf("%d",ans-1);
    64     return 0;
    65 }
    AC代码
  • 相关阅读:
    心得
    第七章
    第六章
    第五章
    第四章
    第三章
    第二章
    第一章
    实验2(4)
    实验2(3)
  • 原文地址:https://www.cnblogs.com/New-ljx/p/13463359.html
Copyright © 2011-2022 走看看