#kruskal,并查集#jzoj 1255 洛谷 2323 公路修建问题

题目

求一个无向图的最小生成树,且最小生成树上的边至少有k条是1级公路(保证单条公路费用一级 ≥ \geq 二级)


分析

kruskal先按一级最小后二级最大排序,求出前 k k k条1级公路,再按二级最小排序求出 n − 1 − k n-1-k n1k条公路


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <climits>
#define rr register
#define min(a,b) ((a)<(b))?(a):(b)
#define max(a,b) ((a)>(b))?(a):(b)
using namespace std;
struct node{int x,y,w1,w2,rk;}e[20001];
int f[10001],n,k,m,t[10001],ans;
inline signed iut(){
    rr int ans=0; rr char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
    return ans;
}
inline signed getf(int u){return f[u]==u?u:f[u]=getf(f[u]);}
signed cmp1(node a,node b){return (a.w1!=b.w1)?(a.w1<b.w1):(a.w2>b.w2);}
signed cmp2(node a,node b){return a.w2<b.w2;}
signed cmp3(node a,node b){return a.rk<b.rk;}
inline void print(int ans){
    if (ans>9) print(ans/10);
    putchar(ans%10+48);
}
signed main(){
    n=iut(),k=iut(),m=iut(); rr int tt=k;
    for (rr int i=1;i<m;++i) e[i]=(node){iut(),iut(),iut(),iut(),i};
    sort(e+1,e+m,cmp1);
    for (rr int i=1;i<=n;++i) f[i]=i;
    for (rr int i=1;i<m;++i){
        rr int fa=getf(e[i].x),fb=getf(e[i].y);
        if (fa==fb) continue;//kruskal思想
        f[min(fa,fb)]=max(fa,fb);
        e[i].w2=INT_MAX;
        ans=max(ans,e[i].w1);
        t[k--]=e[i].rk; if (!k) break;
    }
    sort(e+1,e+m,cmp2);
    for (rr int i=1;i<m;++i)
    if (e[i].w2!=INT_MAX){
        rr int fa=getf(e[i].x),fb=getf(e[i].y);
        if (fa==fb) continue;
        f[min(fa,fb)]=max(fa,fb);
        ans=max(ans,e[i].w2);
        t[++tt]=e[i].rk; if (tt==n-1) break; //选完n-1条边
    }
    sort(t+1,t+n); sort(e+1,e+m,cmp3); print(ans);
    for (rr int i=1;i<n;++i){
        putchar(10); print(t[i]);
        putchar(32); putchar(50-(e[t[i]].w2==INT_MAX));//睿智输出
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值