poj 1679 The Unique MST ( 次小生成树 )

(n^3) -- kruskal 枚举边

 

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#define N 110
#define inf 99999999
using namespace std;
struct node
{
    int x,y,len;
}root[N*N];
int n,m,num[N];
int top,stack[N];

int find(int x)
{
    if(num[x] == x) return x;
    return num[x] = find(num[x]);
}
int cmp(node a,node b)
{
    return a.len<b.len;
}
int kruskal(int pos)
{
    if(pos==-1) top=0;
    for(int i=1;i<=n;i++) num[i]=i;
    int ans=0,cnt=0;
    for(int i=0;i<m;i++)
    {

        if(i==pos) continue ;
        int tx=find(root[i].x);
        int ty=find(root[i].y);
        if(tx!=ty)
        {
          num[ty]=tx;cnt++;
          ans+=root[i].len;
          if(pos==-1)
            stack[top++]=i;
          if(cnt==n-1) break;
        }

    }
    if(cnt!=n-1) return -1;
    return ans;
}

int main()
{
    int cs;cin>>cs;
    while(cs--)
    {
        memset(root,0,sizeof(root));
        memset(stack,0,sizeof(stack));
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        scanf("%d%d%d",&root[i].x,&root[i].y,&root[i].len);

        sort(root,root+n,cmp);
        int minf=kruskal(-1);

        int tmin=inf,t;
        for(int i=0;i<top;i++)
        {
            t=kruskal(stack[i]);
            if(t!=-1&&t<tmin)
            tmin=t;
        }

        if(minf==tmin) puts("Not Unique!");
        else printf("%d\n",minf);
    }
    return 0;
}

(n^2) prim

理解不是太清晰,先放个模版吧

#include<cstdio>
#include<cstring>
#include<cstdlib>
const int inf = 0x3f3f3f3f;
const int N = 105;
bool Tlink[N][N], vis[N];
int w[N][N], lowc[N], pre[N], max[N][N];
int n, m;

int Max( int a, int b)
{
    return a > b ? a : b;
}

int prim()
{
    int i, j, p, k;
    int minc, res = 0;
    memset( vis, false, sizeof vis);
    memset( pre, 0, sizeof pre);
    memset( max, 0, sizeof max);
    vis[1] = 1;pre[1] = 1;

    for( i = 2; i <= n; i ++)  { lowc[i] = w[1][i]; pre[i] = 1;}
    for( i = 2; i <= n; i ++)
    {
        minc = inf; p = -1;
        for( j = 1; j <= n; j ++)
        if( !vis[j] && lowc[j] < minc)
        minc = lowc[j], p = j;

        vis[p] = true;
        res += minc;
        max[ pre[p] ][p] = minc;
        Tlink[ pre[p] ][p] = true;
        Tlink[p][ pre[p] ] = true;
        for( k = 1; k <= n; k ++)
            max[k][p] = Max( max[ pre[p] ][p], max[k][p]);
        for( j = 1; j <= n; j ++)
            if( !vis[j] && lowc[j] > w[p][j])
                lowc[j] = w[p][j],pre[j] = p;
    }
    return res;
}

int main()
{
    int T;scanf( "%d", &T);
    while( T --)
    {
        int s, e, t, Ans, ans;
        scanf( "%d%d", &n, &m);
        for( int i = 1; i <= n; i ++)
        for( int j = 1; j <= n; j ++)
        w[i][j] = inf;

        memset( Tlink, false, sizeof Tlink);
        for( int i = 1; i <= m; i ++)
        {
            scanf( "%d%d%d", &s, &e, &t);
            w[s][e] = w[e][s] = t;
        }
        bool ok = true;
        Ans = prim();
        for( int i = 1; i <= n; i ++)
        {
            for( int j = 1; j <= n; j ++)
            {
                if( w[i][j] == inf || Tlink[i][j])
                    continue;
                ans = Ans + w[i][j] - max[i][j];
                if( Ans == ans)
                {
                    ok = false; break;
                }
            }
            if( ! ok ) break;
        }
        if( ok) printf( "%d\n", Ans);
        else printf( "Not Unique!\n");
    }
    return 0;
}
posted @ 2012-05-09 01:33  skyming  阅读(400)  评论(0编辑  收藏  举报