poj 1679 次小生成树

来源:互联网 发布:科密xc 55a数据库安装 编辑:程序博客网 时间:2024/05/20 09:08

题意:求次小生成树是否存在.
法一:直接判断是否有除最小生成树以外的边。

#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int inf = 0x3f3f3f3f;const int MAXN =105;bool vis[MAXN][MAXN];bool use[MAXN];int pre[MAXN];int n;int G[MAXN][MAXN];int m[MAXN][MAXN];int dist[MAXN];int prim(){    memset(use, false, sizeof(use));    memset(m, 0, sizeof(m));    for(int i=1; i<=n; ++i)    {        pre[i]=1;        dist[i]=G[i][1];    }    int sum=0;    use[1]=true;    int fa;    for(int i=1;i<n;++i)    {        int Min=inf, v=-1;        for(int j=1;j<=n;++j)        {            if(!use[j]&&dist[j]<Min)                Min=dist[v=j];        }        if(Min==inf)           return sum;        use[v]=true;        sum+=Min;        fa=pre[v];        vis[fa][v]=vis[v][fa]=false;        m[fa][v]=m[v][fa]=Min;        for(int j=1;j<=n;++j)            m[v][j]=max(m[fa][v], m[j][fa]);        for(int j=1;j<=n;++j)        {            if(!use[j]&&dist[j]>G[j][v])            {               dist[j]=G[j][v];               pre[j]=v;            }        }    }    return sum;}bool judge(){    //int ans=inf;    for(int i=1; i<=n; ++i)    {        for(int j=1; j<=n; ++j)        {            if(vis[i][j]==false||G[i][j]==inf)                continue;            //ans=min(ans, Min+G[i][j]-m[i][j]);            if(m[i][j]==G[i][j])                return true;        }    }    return false;}int main(){    int t, m;    scanf("%d",&t);    while(t--)    {        scanf("%d%d", &n, &m);        int u, v, w;        memset(vis, false, sizeof(vis));        for(int i=0; i<105; ++i)        {            for(int j=i+1; j<105; ++j)            {                if(i==j)                    G[i][j]=0;                else                    G[i][j]=G[j][i]=inf;            }        }        for(int i=1; i<=m; ++i)        {            scanf("%d %d %d",&u, &v, &w);            G[u][v]=G[v][u]=w;            vis[u][v]=vis[v][u]=true;        }        int ans = prim();        if(judge())            printf("Not Unique!\n");        else            printf("%d\n", ans);    }    return 0;}

法二:计算出次小生成树, 判断是否相等

#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int inf = 0x3f3f3f3f;const int MAXN =105;bool vis[MAXN][MAXN];bool use[MAXN];int pre[MAXN];int n;int G[MAXN][MAXN];int m[MAXN][MAXN];int dist[MAXN];int prim(){    memset(use, false, sizeof(use));    memset(m, 0, sizeof(m));    for(int i=1; i<=n; ++i)    {        pre[i]=1;        dist[i]=G[i][1];    }    int sum=0;    use[1]=true;    int fa;    for(int i=1;i<n;++i)    {        int Min=inf, v=-1;        for(int j=1;j<=n;++j)        {            if(!use[j]&&dist[j]<Min)                Min=dist[v=j];        }        if(Min==inf)           return -1;        sum+=Min;        fa=pre[v];        use[v]=true;        vis[fa][v]=vis[v][fa]=false;        m[fa][v]=m[v][fa]=Min;        for(int j=1;j<=n;++j)            m[v][j]=max(m[fa][v], m[j][fa]);        for(int j=1;j<=n;++j)        {            if(!use[j]&&dist[j]>G[j][v])            {               dist[j]=G[j][v];               pre[j]=v;            }        }    }    return sum;}int judge(int Min){    int ans=inf;    for(int i=1; i<=n; ++i)    {        for(int j=1; j<=n; ++j)        {            if(vis[i][j]==false||G[i][j]==inf)                continue;            ans=min(ans, Min+G[i][j]-m[i][j]);        }    }    return ans;}int main(){    int t, m;    scanf("%d",&t);    while(t--)    {        scanf("%d%d", &n, &m);        int u, v, w;        memset(vis, false, sizeof(vis));        for(int i=0; i<105; ++i)        {            for(int j=i+1; j<105; ++j)            {                if(i==j)                    G[i][j]=0;                else                    G[i][j]=G[j][i]=inf;            }        }        for(int i=1; i<=m; ++i)        {            scanf("%d %d %d",&u, &v, &w);            G[u][v]=G[v][u]=w;            vis[u][v]=vis[v][u]=true;        }        int ans = prim();        if(ans==-1||judge(ans)==ans)            printf("Not Unique!\n");        else            printf("%d\n", ans);    }    return 0;}
原创粉丝点击