Is There A Second Way Left? (UVA 10462)【kruskal 求次小生成树存在】

来源:互联网 发布:如何清空淘宝自动推荐 编辑:程序博客网 时间:2024/05/18 03:10

UVA 10462
题意:求连通图的最小和次小长度,三种情况:1.不存在最小 2.不存在次小 3.最小和次小不同。
题解:无法使用prim求次小生成树,因为可能有两个点有两个及以上权值,那么我们用prim会把大的权值覆盖掉,所以我们用kruskal求,怎么求呢?我们求出最小生成树后,把用过的边绕过,求最小生成树,如果存在则存在。我开始题意理解有误,我以为次小和最小相同是第2种情况。。。wa了一次。

ac代码

#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<queue>using namespace std;#define INF 0x3f3f3f3ftypedef long long LL;const double PI = acos(-1.0);const int mod = 1e9 + 7;const int N = 210;int n,m;struct Eage{    int x,y,v;}e[N];bool cmp(Eage a,Eage b){    return a.v < b.v;}int fa[N];int record[N];int Find(int x){    if(fa[x] != x)        fa[x] = Find(fa[x]);    return fa[x];}void init(){    for(int i = 1; i <= n; i ++)        fa[i] = i;}int main(){    int tcase;    scanf("%d",&tcase);    int f = 1;    while(tcase--)    {        scanf("%d%d",&n,&m);        for(int i = 0; i < m; i++)            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v);        printf("Case #%d : ",f++);        init();        int ans = 0;        int k = 0;        sort(e,e+m,cmp);        for(int i = 0; i < m; i++)        {            int dx = Find(e[i].x);            int dy = Find(e[i].y);            if(dx != dy)            {                fa[dx] = dy;                ans += e[i].v;                record[k] = i;                k++;            }            if(k == n-1)                break;        }        if(k != n-1)        {            printf("No way\n");            continue;        }        int da = INF;        for(int i = 0; i < k; i++)        {            init();            int kk = 0, ansans = 0;            for(int j = 0; j < m; j++)            {                if(j == record[i])                    continue;                int dx = Find(e[j].x);                int dy = Find(e[j].y);                if(dx != dy)                {                    fa[dx] = dy;                    ansans += e[j].v;                    kk ++;                }                if(kk == n-1)                    break;            }            if(kk == n-1)                da = min(ansans,da);        }        if(da == INF)            printf("No second way\n");        else            printf("%d\n",da);    }    return 0;}
0 0