• P3623 [APIO2008]免费道路


    3624: [Apio2008]免费道路

    Time Limit: 2 Sec Memory Limit: 128 MBSec Special Judge
    Submit: 2143 Solved: 881
    [Submit][Status][Discuss]

    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条即可


    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define LL long long
    using namespace std;
    
    int i,m,n,j,k,x,y,z,f[100001],c1,c2,bl[500001],cnt1,cnt2;
    struct vv
    {
        int x,y;
    } b[500001],w[500001];
    
    int find(int x)
    {
        if(f[x]==x) return x;
        f[x]=find(f[x]);
        return f[x];
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(i=1;i<=n;i++) f[i]=i;
        
        for(i=1;i<=m;i++) 
        {
            scanf("%d%d%d",&x,&y,&z);
            if(z) { c1+=1; b[c1].x=x, b[c1].y=y;}
            else {c2+=1; w[c2].x=x; w[c2].y=y;}
        }
        if(c2<k) {printf("no solution
    "); return 0;}
        
        for(i=1;i<=c1;i++)	if(find(b[i].x)!=find(b[i].y)) f[f[b[i].x]]=f[b[i].y], cnt1+=1;
        
        if(cnt1<n-1-k) {printf("no solution
    "); return 0;}
        
        for(i=1;i<=c2;i++)	if(find(w[i].x)!=find(w[i].y)) bl[i]=1, f[f[w[i].x]]=f[w[i].y], cnt2+=1;
        
        if(cnt1+cnt2!=n-1) 	{printf("no solution
    "); return 0;}
    
        for(i=1;i<=n;i++) f[i]=i;  	k-=cnt2;
    
        for(i=1;i<=c2;i++)
            if(bl[i]) f[find(w[i].x)]=find(w[i].y);
            else if(k && find(w[i].x)!=find(w[i].y)) bl[i]=1, f[f[w[i].x]]=f[w[i].y], k-=1;
            
        if(k) {printf("no solution
    "); return 0;}
        
        for(i=1;i<=c1;i++)
            if(find(b[i].x)!=find(b[i].y)) 
            {
                printf("%d %d 1
    ",b[i].x, b[i].y);
                f[f[b[i].x]]=f[b[i].y];
            }
        for(i=1;i<=c2;i++) if(bl[i]) printf("%d %d 0
    ",w[i].x,w[i].y);
    }
    
  • 相关阅读:
    电路维修 (广搜变形-双端队列bfs)
    靶形数独 (dfs+预处理+状态压缩)
    埃及分数问题(带乐观估计函数的迭代加深搜索算法-IDA*)
    weight (搜索对象的选取)
    Codeforces Round #506 (Div. 3)
    生日蛋糕 (poj1190) (dfs剪枝)
    校内模拟赛题面
    NOIP2013 D1T3 货车运输 zz耻辱记
    NOIP2011 D2T3 观光公交 做题笔记
    ARC 103
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/9872788.html
Copyright © 2020-2023  润新知