• bzoj3624(铺黑白路)(并查集维护)


    题意网上自己随便找,绝对是找的到的。

    题解:(白边表示鹅卵石路,黑边表示水泥路)这道题的解法,先考虑将黑边所有都先连起来,组成一个又一个的联通块,然后用白边去连,

    如果可以联通的话,就用白边去代替黑边,必要的白边(就是维护联通性的白边必须要先保证),然后再去代替,直到k条边满足,不满足则输出NO

    然后就再用黑边去连,记录,反正是Special Judge所以顺序没有关系,就好了。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 typedef long long ll;
     9 const int INF=1e9+7,NN=20007,MM=100007;
    10 
    11 int n,m,K,top;
    12 int fa[NN];
    13 int u[MM],v[MM],c[MM];
    14 int au[NN],av[NN],ac[NN];
    15 bool mark[MM];
    16 int num[2];
    17 
    18 int find(int num)
    19 {
    20     if (fa[num]==num) return num;
    21     else fa[num]=find(fa[num]);
    22     return fa[num];
    23 }
    24 void solve(bool typ,int up)
    25 {
    26     for(int i=1;i<=m;i++)
    27         if(c[i]==typ&&num[typ]<up)
    28         {
    29             int p=find(u[i]),q=find(v[i]);
    30             if(p!=q)
    31             {
    32                 fa[p]=q;
    33                 au[++top]=u[i],av[top]=v[i],ac[top]=c[i];
    34                 mark[i]=1;
    35                 num[typ]++;
    36             }
    37         }
    38 }
    39 void init()
    40 {
    41     memset(mark,0,sizeof(mark));
    42     scanf("%d%d%d",&n,&m,&K);
    43     for(int i=1;i<=m;i++) 
    44         scanf("%d%d%d",&u[i],&v[i],&c[i]);
    45     for(int i=1;i<=n;i++)
    46         fa[i]=i;
    47 }
    48 int main()
    49 {
    50     init();
    51     
    52     num[0]=num[1]=0;
    53     solve(1,INF),solve(0,INF);
    54     if(num[1]+num[0]!=n-1||num[0]>K)
    55     {
    56         puts("no solution
    ");
    57         return 0;
    58     }//及如果需要>k条鹅卵石路将各个块连起来,或者需要多余n-1条边
    59     
    60     top=num[0]=num[1]=0;//然后用鹅卵石重新铺 
    61     for(int i=1;i<=n;i++)
    62         fa[i]=i;
    63     for(int i=1;i<=m;i++)
    64         if(c[i]==0&&mark[i])
    65         {
    66             int p=find(u[i]),q=find(v[i]);
    67             if(p!=q)
    68             {
    69                 num[0]++;fa[p]=q;
    70                 au[++top]=u[i];av[top]=v[i];ac[top]=c[i];
    71             }
    72         }//必要的先铺满
    73     solve(0,K),solve(1,INF);//然后再不必要鹅卵石的取铺,然后再用水泥路取铺就可以了。 
    74     if(num[0]<K)
    75     {
    76         puts("no solution");
    77         return 0;
    78     }
    79     for(int i=1;i<=top;i++)
    80         printf("%d %d %d
    ",au[i],av[i],ac[i]);
    81 }
  • 相关阅读:
    oracle 11g 数据库密码大小写敏感性更改
    OGG 课程 第一课
    xmanager
    一步一步在RHEL6.5+VMware Workstation 10上搭建 oracle 11gR2 rac + 物理 dg
    GTONE安装Eclipse插件
    JDK安装与环境变量配置
    JAVA基础
    操作符总结
    物理CPU查看方式
    SQL SERVER性能调优
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7429659.html
Copyright © 2020-2023  润新知