码迷,mamicode.com
首页 > Windows程序 > 详细

BZOJ 3624: [Apio2008]免费道路 [生成树 并查集]

时间:2017-03-21 18:22:19      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:line   turn   har   for   get   color   char   bzoj   并查集   

题意:

一张图0,1两种边,构造一个恰有k条0边的生成树


 

优先选择1边构造生成树,看看0边是否小于k

然后保留这些0边,补齐k条,再加1边一定能构成生成树

类似kruskal的证明

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=2e4+5, M=1e5+5;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}

int n, m, k, u, v, c, m0, m1, p;
struct meow{int u, v, c;}a[M], b[M], ans[N];
int fa[N];
int find(int x) {return x==fa[x] ? x : fa[x]=find(fa[x]);}
int flag[N];
int main() {
    freopen("in","r",stdin);
    n=read(); m=read(); k=read();
    for(int i=1; i<=m; i++) {
        u=read(), v=read(), c=read();
        if(c==1) a[++m1]=(meow){u,v,c};
        else b[++m0]=(meow){u,v,c};
    }

    int cnt=0;
    for(int i=1; i<=n; i++) fa[i]=i;
    for(int i=1; i<=m1; i++) {
        u=a[i].u, v=a[i].v;
        int x=find(u), y=find(v);
        if(x==y) continue;
        fa[x]=y;
        if(++cnt == n-1) break;
    }
    for(int i=1; i<=m0; i++) {
        u=b[i].u, v=b[i].v;
        int x=find(u), y=find(v);
        if(x==y) continue;
        fa[x]=y; ans[++p]=b[i]; flag[i]=1;
        if(++cnt == n-1) break;
    }
    if(p > k || cnt < n-1) {puts("no solution"); return 0;}

    for(int i=1; i<=n; i++) fa[i]=i;
    for(int i=1; i<=p; i++) fa[find(ans[i].u)] = find(ans[i].v);
    cnt=p;
    if(cnt<k) for(int i=1; i<=m0; i++) if(!flag[i]){
        u=b[i].u, v=b[i].v;
        int x=find(u), y=find(v);
        if(x==y) continue;
        fa[x]=y; ans[++cnt]=b[i];
        if(cnt == k) break;
    }
    for(int i=1; i<=m1; i++) {
        u=a[i].u, v=a[i].v;
        int x=find(u), y=find(v);
        if(x==y) continue;
        fa[x]=y; ans[++cnt]=a[i];
        if(cnt == n-1) break;
    }
    for(int i=1; i<=cnt; i++) printf("%d %d %d\n",ans[i].u, ans[i].v, ans[i].c);
}

 

BZOJ 3624: [Apio2008]免费道路 [生成树 并查集]

标签:line   turn   har   for   get   color   char   bzoj   并查集   

原文地址:http://www.cnblogs.com/candy99/p/6595978.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!