UVA10462_Is There A Second Way Left? _kruskal的次小生成树

来源:互联网 发布:面试问hash算法 编辑:程序博客网 时间:2024/06/08 14:46

题意

给 n 个点 和 m 条边,问最小生成树是否存在,次小生成树是否存在,次小生成树是几。特别的,有重边。

思路

本来次小生成树问题习惯用 prim 来解决,但本题中有重边,不适合用邻接矩阵表示,模板就用不上了。
有重边的情况下还是 kruskal 比较好用。

题目链接

这里给出的是 VJudge 的链接
https://vjudge.net/contest/169042#problem/D

AC代码

#include<cstdio>#include<iostream>#include<cstring>#include<queue>#include<algorithm>using namespace std;const int maxn = 100 + 10;const int maxm = 200 + 10;const int  inf = 0x3f3f3f3f;int cas, n, m;int x, y, c;int s1, s2;struct edge{    int s, t, c;    edge(){}    edge(int _s, int _t, int _c)    :s(_s), t(_t), c(_c){}    bool operator < (edge x)    {        return c < x.c;    }};edge E [maxm];int path[maxm];int it;int root[maxn << 2], ran[maxn << 2];void init(){    memset(root, -1, sizeof root);    memset(ran, 0, sizeof ran);}int Uf(int x){    if(root[x] == -1) return x;    return root[x] = Uf(root[x]);}void Union(int x, int y){    x = Uf(x), y = Uf(y);    if(x == y) return;    if(ran[x] < ran[y]) root[x] = y;    else root[y] = x;    if(ran[x] == ran[y]) ran[x] ++;}int kruskal(){    init();    int smt = 0, tree = n;    for(int i= 0; i< m && tree > 1; i++)    {        int u = E[i].s, v = E[i].t, cost = E[i].c;        if(Uf(u) == Uf(v)) continue;        if(cost == inf) continue;        if(s1 == -1) path[it] = i, it ++;        smt += cost;        tree --;        Union(u, v);    }    if(tree == 1) return smt;    return -1;}int main(){    scanf("%d", &cas);    int Cas = 0;    while(cas --)    {        s1 = -1, s2 = -1, it = 0;        printf("Case #%d : ", ++ Cas);        scanf("%d %d", &n, &m);        for(int i= 0; i< m; i++)        {            scanf("%d %d %d", &x, &y, &c);            E[i] = edge(x, y, c);        }        sort(E, E+m);        s1 = kruskal();        if(s1 == -1)        {            printf("No way\n");            continue;        }        for(int i= 0; i< it; i++)        {            int e = path[i];            int temp = E[e].c;            E[e].c = inf;            int d = kruskal();            if(d != -1 && (s2 == -1 || s2 > d)) s2 = d;            E[e].c = temp;        }        if(s2 == -1)        {            printf("No second way\n");            continue;        }        printf("%d\n", s2);    }    return 0;}
原创粉丝点击