bzoj3624: [Apio2008]免费道路

Posted Nico&11101001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3624: [Apio2008]免费道路相关的知识,希望对你有一定的参考价值。

目录



题目链接

bzoj3624: [Apio2008]免费道路

题解

两边kruskal分别找出必须保留的石子路和软石路
剩下的随便填满k就ok了

代码

#include<map> 
#include<vector> 
#include<cstdio> 
#include<algorithm> 
#define gc getchar()
#define pc putchar 
inline int read() { 
    int x = 0,f = 1; 
    char c = gc; 
    while(c < '0' || c > '9')c = gc; 
    while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = gc; 
    return x * f; 
}
void print(int x) { 
    if(x < 0) { 
        pc('-'); 
        x = -x; 
    } 
    if(x >= 10) print(x / 10); 
    pc(x % 10 + '0'); 
} 
const int maxn = 2000007; 
int a[maxn]; 
int n,m,k; 
struct node { 
    int u,v,w,tag; 
} e[maxn]; 
int num = 0; 
int fa[maxn]; 
inline void add(int a,int b,int c) { 
    e[++ num].u = a,e[num].v = b; e[num].w = c; 
} 
inline bool c1(node a,node b) {
    return a.w < b.w; 
} 
inline bool c2(node a,node b) { 
    return a.w > b.w; 
} 
int find(int x) { 
    if(x != fa[x]) fa[x] = find(fa[x]); 
    return fa[x]; 
} 
int main() {
    n = read(),m = read(),k = read(); 
    for(int u,v,w,i = 1;i <= m;++ i) { 
        u = read(),v = read(),w = read(); 
        add(u,v,w); 
    } 
    for(int i = 1;i <= n;++ i) fa[i] = i; 
    std::sort(e + 1,e + m + 1,c2); 
    int cnt = 0; 
    for(int i = 1;i <= m;++ i)  {
        int fx = find(e[i].u),fy = find(e[i].v); 
        if(fx != fy) {
            fa[fx] = fy; 
            if(!e[i].w) e[i].tag = 1,cnt ++; 
        } 
    }  
    if(cnt > k) { 
        puts("no solution"); 
        return 0; 
    }    
    for(int i = 1;i <= n;++ i) fa[i] = i; 
    for(int i = 1;i <= m;++ i) 
        if(e[i].tag) fa[find(e[i].u)] = fa[find(e[i].v)]; 
    std::sort(e + 1,e + m + 1,c1) ; 
    for(int i = 1;i <= m;++ i) { 
        if(e[i].w) break; 
        int fx = find(e[i].u),fy =  find(e[i].v); 
        if(fx != fy) { 
            fa[fx] = fy; 
            ++ cnt; 
            e[i].tag = 1; 
        } 
        if(cnt == k) break; 
    } 
    if(cnt < k) { 
        puts("no solution"); 
        return 0; 
    } 
    std::sort(e + 1,e + m + 1,c2); 
    for(int i = 1;i <= m;++ i)  { 
        if(!e[i].w) break; 
        int fx = find(e[i].u),fy = find(e[i].v); 
        if(fx != fy) { 
            fa[fx] = fy; 
            e[i].tag = 1; 
        } 
    } 
    for(int i = 1;i <= m;++ i) 
        if(e[i].tag) { 
            print(e[i].u);pc(' '); 
            print(e[i].v);pc(' '); 
            print(e[i].w);pc('\n'); 
            
        } 
    return 0; 
} 

以上是关于bzoj3624: [Apio2008]免费道路的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3624: [Apio2008]免费道路

bzoj3624Apio2008—免费道路

Bzoj 3624: [Apio2008]免费道路 (贪心+生成树)

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

Kruskal+贪心思想BZOJ3624-[Apio2008]免费道路

BZOJ 3624 [Apio2008]免费道路:并查集 + 生成树 + 贪心恰有k条特殊路径