zoukankan      html  css  js  c++  java
  • bzoj3624,[Apio2008]免费道路

    题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=3624

    Description

    Input

    Output

    Sample Input

    5 7 2
    1 3 0
    4 5 1
    3 2 0
    5 3 1
    4 3 0
    1 2 1
    4 2 1 

    Sample Output

    3 2 0
    4 3 0
    5 3 1
    1 2 1

    题解

     首先有一些鹅卵石的路是必须选的,那么可以先把马路的做一遍最小生成树,若不连通,则往里面加鹅卵石的路使其连通,这个时候加的边都为必须加的。接着再做一遍最小生成树,先把上一次找出的必加的边加进去,再往里面加鹅卵石的边,使其到达k条,若不连通,加马路,这时选的边加上第一遍必须选的边即为答案

    代码解释

    q标记的是这次操作是在找答案还是找必须选的鹅卵石的边。b[]记录的是边有没有选,第一次找必加的边的时候只要记录鹅卵石边有没有加,第二次则需要记录所有的边

    代码

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #define N 20010
    #define M 100010
    using namespace std;
    struct data{int u,v,c;}a[M];
    int fa[N],b[M];
    int m,x,y,all,sum,q,k,n;
    int getint()
    {
        int res=0,w=1;
        char ch=getchar();
        while ((ch>'9' || ch<'0')&&ch!='-') ch=getchar();
        if (ch=='-') w=-1,ch=getchar();
        while (ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();
        return res*w;
    }
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    void add(int p)
    {
        for (int i=1;i<=m;i++)
            {
                if (a[i].c==p)
                    {
                        x=find(a[i].u); y=find(a[i].v);
                        if (x!=y)
                            {
                                all++; fa[x]=fa[y];
                                if (q) b[i]=1;
                                if (!p) {b[i]=1; sum++; if (q&&sum==k) return;}
                            }
                    }
            }
    }
    int main()
    {
        n=getint(); m=getint(); k=getint();
        for (int i=1;i<=m;i++)
            a[i].u=getint(),a[i].v=getint(),a[i].c=getint();
    
        for (int i=1;i<=n;i++) fa[i]=i;
        all=0; add(1); add(0); 
        if (all!=n-1||sum>k) {printf("no solution
    "); return 0;}
    
        for (int i=1;i<=n;i++) fa[i]=i; sum=0;
        for (int i=1;i<=m;i++)
            if (b[i]) sum++,x=find(a[i].u),y=find(a[i].v),fa[x]=y;
        q=1;
        if (sum!=k) add(0);
        add(1);
    
        if (sum<k) {printf("no solution
    "); return 0;}
        for (int i=1;i<=m;i++)
            if (b[i]) printf("%d %d %d
    ",a[i].u,a[i].v,a[i].c);
        return 0;
    }
    转载请联系博主!!!
  • 相关阅读:
    python 得到列表的第二大的元素
    PHP 打印输出数组内容及结构 print_r 与 var_dump 函数
    php 数组元素加法
    PHP unlink() 函数
    PHP 文件创建/写入
    PHP chmod() 函数
    php 压缩文件
    php 每隔30s在页面显示字符串
    PHP basename() 函数
    PHP rtrim() 函数
  • 原文地址:https://www.cnblogs.com/xiaoqiang200015/p/5975081.html
Copyright © 2011-2022 走看看