zoukankan      html  css  js  c++  java
  • POJ 1679 The Unique MST --Kruskal应用

    这题可以用次小生成树解,这里用Kruskal算法来做。每条边除维护u,v,w外,还维护:

    used:表示这条边是否加过 

    eq:表示有没有与这条边相等的边

    del:删除标记,以便删边之用

    如果对于一个最小生成树的的边A,有一条与之权值相等的边B,则考虑把A删掉,再求一次最小生成树,看求出的总权值是否与前一个最小生成树的总权值相等。如果相等,则不唯一,如果找遍了这些权值相等的边都没找到,就说明唯一(注意每次不相等的话要把A重新加进来)。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 107
    
    struct Edge
    {
        int u,v,w;
        bool eq,del,used;
    }edge[N*N];
    
    int cmp(Edge ka,Edge kb)
    {
        return ka.w < kb.w;
    }
    
    int fa[N],n,m,first;
    
    int findset(int x)
    {
        if(x != fa[x])
            fa[x] = findset(fa[x]);
        return fa[x];
    }
    
    int Kruskal()
    {
        int i,j,k = 0;
        int sum = 0;
        for(i=1;i<=n;i++)
            fa[i] = i;
        for(i=1;i<=m;i++)
        {
            if(edge[i].del)
                continue;
            int u = edge[i].u;
            int v = edge[i].v;
            int fx = findset(u);
            int fy = findset(v);
            if(fx != fy)
            {
                sum += edge[i].w;
                fa[fx] = fy;
                if(first)
                    edge[i].used = 1;
                k++;
            }
            if(k >= n-1)
                break;
        }
        return sum;
    }
    
    int main()
    {
        int t,i,j,u,v,w;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                edge[i].u = u;
                edge[i].v = v;
                edge[i].w = w;
                edge[i].del = edge[i].used = edge[i].eq = 0;
            }
            for(i=1;i<=m;i++)
            {
                for(j=1;j<=m;j++)
                {
                    if(i == j)
                        continue;
                    if(edge[i].w == edge[j].w)
                        edge[i].eq = 1;
                }
            }
            sort(edge+1,edge+m+1,cmp);
            first = 1;
            int w1 = Kruskal();
            int w2;
            first = 0;
            for(i=1;i<=m;i++)
            {
                if(edge[i].used && edge[i].eq)
                {
                    edge[i].del = 1;
                    w2 = Kruskal();
                    if(w1 == w2)
                    {
                        puts("Not Unique!");
                        break;
                    }
                    edge[i].del = 0;
                }
            }
            if(i > m)
                printf("%d
    ",w1);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【简报】一款使用静态图片生成动画的jQuery插件:JZoopraxiscope
    使用jQuery timelinr和animate.css创建超酷的CSS动画时间轴特效
    超酷信息图分享:你属于哪类geek?
    数据库操作优化
    android R.java aapt
    xml sax 解析 & 符号
    sql server2000 完全卸载
    cmd 命令总结
    手动打包 解释
    bat 执行 java jar包
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3633729.html
Copyright © 2011-2022 走看看