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

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

ac代码

#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
typedef 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;
}

你可能感兴趣的:(图论)