【UVA10462】【好题】【次小生成树并查集算法】

来源:互联网 发布:2017苹果mac桌面壁纸 编辑:程序博客网 时间:2024/06/05 08:32





#include <iostream>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <list>#include <map>#include <set>#include <string>#include <cstdlib>#include <cstdio>#include <algorithm>using namespace std;#define rep(i,a,n) for (int i=a;i<n;i++)#define per(i,a,n) for (int i=n-1;i>=a;i--)#define mp push_backint T;int n,m;struct Edge{    int u,v,w;}edge[30000];int used[30000];int cmp(Edge a,Edge b){    return a.w < b.w;}int F[15000];int len;int find(int x){    return F[x] == -1?x : find(F[x]);}int kru(int del){    for(int i=0;i<1400;i++) F[i] = -1;    int ret = 0;    for(int i=0;i<m;i++)    {        if(i == del) continue;        int fx = find(edge[i].u);        int fy = find(edge[i].v);        if(fx != fy)        {            ret += edge[i].w;            if(del == -1)            used[len++] = i;            F[fx] = fy;        }    }    int fnums = 0;    for(int i=1;i<=n;i++)    {        if(F[i] == -1) fnums ++;    }    if(fnums >= 2) return 0x3f3f3f3f;     return ret;}int main(){      scanf("%d",&T);    int C = 1;    while(T --)    {        scanf("%d%d",&n,&m);        len = 0;        memset(used,0,sizeof(used));        for(int i=0;i<m;i++)        {            int u,v,w;            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);        }        sort(edge,edge+m,cmp);        int stm = kru(-1);        if(stm == 0x3f3f3f3f)        {            printf("Case #%d : No way\n",C++);            continue;        }        int ans = 0x3f3f3f3f;        for(int i=0;i<n-1;i++)        {            int del = used[i];            ans = min(ans,kru(del));        }           if(ans == 0x3f3f3f3f)        {            printf("Case #%d : No second way\n",C++);        }        else        {            printf("Case #%d : %d\n",C++,ans);        }    }}


0 0
原创粉丝点击