bzoj 1196

思路:最小生成树水题

#include
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair

using namespace std;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +7;

int n, m, k, fa[N];

struct node {
    int u, v, c1, c2;
}edge[N];

bool cmp1(const node &a, const node &b) {
    return a.c1 < b.c1;
}

bool cmp2(const node &a, const node &b) {
    return a.c2 < b.c2;
}

int getRoot(int x) {
    return fa[x] == x ? x : getRoot(fa[x]);
}

int kruskal() {
    for(int i = 1; i <= n; i++) {
        fa[i] = i;
    }

    sort(edge, edge + m, cmp2);

    int cnt = 0, ans = 0;

    for(int i = 0; i < m; i++) {
        int u = edge[i].u;
        int v = edge[i].v;
        int c = edge[i].c2;

        int x = getRoot(u);
        int y = getRoot(v);

        if(x != y) {
            fa[x] = y;
            cnt++;
            ans = max(ans, c);
            if(cnt == k) break;
        }
    }

    sort(edge, edge + m, cmp1);

    for(int i = 0; i < m; i++) {
        int u = edge[i].u;
        int v = edge[i].v;
        int c = edge[i].c1;

        int x = getRoot(u);
        int y = getRoot(v);

        if(x != y) {
            fa[x] = y;
            cnt++;
            ans = max(ans, c);
            if(cnt == n - 1) break;
        }
    }
    return ans;
}
int main() {
    scanf("%d%d%d", &n, &k, &m);
    m--;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d%d", &edge[i].u, &edge[i].v, &edge[i].c2, &edge[i].c1);
    }
    int ans = kruskal();


    printf("%d\n", ans);
    return 0;
}
/*
*/

 

转载于:https://www.cnblogs.com/CJLHY/p/9193617.html

你可能感兴趣的:(bzoj 1196)