zoukankan      html  css  js  c++  java
  • APIO2008 洛谷P3623 免费道路

    题目传送门:https://www.luogu.org/recordnew/show/6743108

    题解:写3次并查集,首先不妨留下所有水泥路,添加石子路,那么添加的石子路一定在答案内,留下所有石子路也一样,最后再添加其他边是等价的,注意k值即可,注意要判断好几次无解的情况。

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #define MN 20005
     4 #define MM 100005
     5 using namespace std;
     6 int n,m,k,fa[MN],u[MM],v[MM],c[MM],ans[MM],cnt;
     7 bool used[MM];
     8 int ff(int x){return fa[x]==x?x:fa[x]=ff(fa[x]);}
     9 bool check(){
    10     int tmp=ff(1);
    11     for(int i=2;i<=n;i++)
    12         if(ff(i)!=tmp) return false;
    13     return true;
    14 }
    15 bool work1(){
    16     for(int i=1;i<=n;i++) fa[i]=i;
    17     for(int i=1;i<=m;i++)
    18         if(c[i]){
    19             int x=ff(u[i]),y=ff(v[i]);
    20             if(x!=y) fa[y]=x;
    21         }
    22     for(int i=1;i<=m;i++)
    23         if(!c[i]){
    24             int x=ff(u[i]),y=ff(v[i]);
    25             if(x!=y) fa[y]=x,ans[++cnt]=i,used[i]=true;
    26         }
    27     if(k<cnt) return false;
    28     else k-=cnt;
    29     if(!check()) return false;
    30     return true;
    31 }
    32 bool work2(){
    33     for(int i=1;i<=n;i++) fa[i]=i;
    34     for(int i=1;i<=m;i++)
    35         if(!c[i]){
    36             int x=ff(u[i]),y=ff(v[i]);
    37             if(x!=y) fa[y]=x;
    38         }
    39     for(int i=1;i<=m;i++)
    40         if(c[i]){
    41             int x=ff(u[i]),y=ff(v[i]);
    42             if(x!=y) fa[y]=x,ans[++cnt]=i,used[i]=true;
    43         }
    44     if(!check()) return false;
    45     return true;
    46 }
    47 bool work3(){
    48     for(int i=1;i<=n;i++) fa[i]=i;
    49     for(int i=1;i<=cnt;i++){
    50         int x=ff(u[ans[i]]),y=ff(v[ans[i]]);
    51         if(x!=y) fa[y]=x;
    52         else return false;
    53     }
    54     for(int i=1;i<=m;i++){
    55         if(!k) break;
    56         if(!used[i]&&!c[i]){
    57             int x=ff(u[i]),y=ff(v[i]);
    58             if(x!=y) fa[y]=x,k--,ans[++cnt]=i;
    59         }
    60     }
    61     if(k) return false;
    62     for(int i=1;i<=m;i++)
    63         if(!used[i]&&c[i]){
    64             int x=ff(u[i]),y=ff(v[i]);
    65             if(x!=y) fa[y]=x,ans[++cnt]=i;
    66         }
    67     if(!check()) return false;
    68     return true;
    69 }
    70 int main()
    71 {
    72     scanf("%d%d%d",&n,&m,&k);
    73     for(int i=1;i<=m;i++) scanf("%d%d%d",&u[i],&v[i],&c[i]);
    74     if(!work1()){puts("no solution");return 0;}
    75     if(!work2()){puts("no solution");return 0;}
    76     if(!work3()){puts("no solution");return 0;}
    77     for(int i=1;i<=cnt;i++)
    78         printf("%d %d %d
    ",u[ans[i]],v[ans[i]],c[ans[i]]);
    79     return 0;
    80 }
  • 相关阅读:
    Python:字典
    Linux基础:dirname命令总结
    (三)封装与类
    (二)Java编程基础
    Ubuntu18.04 安装QQ、Tim、微信与win无差异
    (一)JDK安装和使用eclipse输出hello world
    Java复习目录
    (八)MySQL事务、视图、变量、存储过程、函数、流程控制结构
    (七)MySQL常见的数据类型、约束和标识列
    (六)MySQL数据、库、表的管理
  • 原文地址:https://www.cnblogs.com/Beginner-/p/8798900.html
Copyright © 2011-2022 走看看