URAL 1416 Confidential <最小生成数和次小生成数>

来源:互联网 发布:清华大学c语言教材 编辑:程序博客网 时间:2024/06/05 00:53

题意:求一幅无向图的最小生成树与最小生成树,不存在输出-1

分析:Kruskal求最小生成树,标记用过的边。求次小生成树时,依次枚举用过的边,将其去除后再求最小生成树,得出所有情况下的最小的生成树就是次小的生成树。可以证明:最小生成树与次小生成树之间仅有一条边不同。

样例:

inputoutput

4 61 2 22 3 23 4 24 1 21 3 12 4 1
Cost: 4Cost: 4
3 21 2 22 3 2
Cost: 4Cost: -1
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>using namespace std;const int MAXN = 505;const int MAXM = 0x7fffffff;int n,m;int use_num ;int wei;struct Edge{    int u,v,w;    bool operator <(const Edge& ee)    {        return w<ee.w;    }}e[MAXN*MAXN];int used[MAXN],pre[MAXN];int finds(int x){    if(pre[x]==-1)        return x;    return pre[x]=finds(pre[x]);}int Kruskal(){    //int flag = 0;.    int fx,fy;    use_num = 0;    wei = 0;    fill_n(pre,n+1,-1);    for(int i = 0;i<m;i++)    {        fx=finds(e[i].u);fy=finds(e[i].v);        if(fx!=fy)        {            pre[fx]=fy;            used[use_num++] = i;            wei+=e[i].w;            if(use_num == n-1)                 return wei;        }    }   // printf("m= %d  use")        return -1;}int sec_kruskal(){    int flag =0;    int fx,fy,count_num;    int num = MAXM;    int sum;    for(int i=0;i<use_num;i++)    {        fill_n(pre,n+1,-1);        count_num = 0;sum=0;flag=0;        for(int j=0;j<m;j++)        {            if(j==used[i])                continue;             fx=finds(e[j].u);fy=finds(e[j].v);            if(fx!=fy)            {                pre[fx]=fy;                count_num++;                sum+=e[j].w;                if(count_num == n-1)               {                      flag = 1;                      break;                 }            }        }        if(flag&&sum<num)        {            num=sum;        }    }    if(num==MAXM)        return -1;    else        return num;}int main(){    //int n,m;    int u,v,w;    int fmin,smin;    while(scanf("%d %d",&n,&m)!=EOF)    {        for(int i=0;i<m;i++)        {            scanf("%d %d %d",&u,&v,&w);            e[i] = (Edge){u,v,w};        }        sort(e,e+m);        fmin = Kruskal();        smin = sec_kruskal();        printf("Cost: %d\n",fmin);        printf("Cost: %d\n",smin);    }}


0 0
原创粉丝点击