美文网首页
次小生成树 UVA --- 10462

次小生成树 UVA --- 10462

作者: Anxdada | 来源:发表于2017-04-06 22:20 被阅读0次

题意就是判断是否存在最小生成树,如果存在,那又是否有次小生成树,有的话输出其值,否则按题意输出.
AC代码: (第一次过的时候时间达到了710ms,我嫌太长了,看那些都是10ms过的,于是不断的改,终于还是10ms也过了,哈哈,vector真的很好用!!!)

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<set>
#include<queue>
#include<functional>
#include<vector>
#include<stack>
#include<map>
#include<cstdlib>
#define CLR(x) memset(x,0,sizeof(x))
#define ll long long int
#define PI acos(-1.0)
#define db double
#define mod 1000000007
using namespace std;
const int maxn = 2005;
const int inf = 1e9;
int cas=1;
int pre[maxn];
int n,m;
vector<int>used;   //申请一个动态数组保存第一次最小生成树用了哪些边. 用数组也行,但是vector更快! 所以多利用它吧.
struct node{ int u,v,w;} s[maxn];    //为了简洁,当然也可以直接展开写.
void init(){ for(int i=0;i<=n;i++) pre[i]=i; }   
int Find(int x){ return pre[x]==x?x:pre[x]=Find(pre[x]); }
bool cmp(node a,node b){ return a.w<b.w; }
int kruskal(int flag)     //flag来标记是第一次进来还是标记过的边进来.
{
    int num=0;
    int sum=0;
    for(int i=0;i<m;i++){
        if(i==flag) continue;    //遇到标记过的边就删除.
        int u=Find(s[i].u);
        int v=Find(s[i].v);
        if( u != v){
            pre[v]=u;
            sum+=s[i].w;
            num++;
            if(flag==-1)
                used.push_back(i);    //用过的边全部保存在used容器中.
        }
        if(num==n-1)
            break;
    }
    int cnt=0;
    for(int i=1;i<=n;i++){    //判断是否是最小生成树.
        if(pre[i]==i)
            cnt++;
    }
    if(cnt>1)
        return inf;
    return sum;
}

int main()
{
    int t;
    cin >> t;
    while(t--){
        scanf("%d %d",&n,&m);
        if(n==1 && m==0){         //特判这一种情况.
            printf("Case #%d : No second way\n",cas++);
            continue;
        }
        init();
        used.clear();
        for(int i=0;i<m;i++){
            scanf("%d %d %d",&s[i].u,&s[i].v,&s[i].w);
        }
        sort(s,s+m,cmp);
        int ans=inf;
        ans=kruskal(-1);
        printf("Case #%d : ",cas++);
        if(ans==inf){
            printf("No way\n");
            continue;
        }
        ans=inf;
        for(int i=0;i<used.size();i++){
            init();
            int use=used[i];
            ans=min(ans,kruskal(use));      //循环选出次小生成树!
        }
        if(ans==inf){
            printf("No second way\n");
            continue;
        }
        printf("%d\n",ans);
    }
}

相关文章

  • 次小生成树 UVA --- 10462

    题意就是判断是否存在最小生成树,如果存在,那又是否有次小生成树,有的话输出其值,否则按题意输出.AC代码: (第一...

  • UVA10766(生成树计数)

    代码改模板没怎么改出来.看的别人的改的,还是有点不懂.

  • Uva(1395)(Slim Span)

    链接:https://vjudge.net/problem/UVA-1395思路:表面看起来跟最小生成树没什么关系...

  • ACM刷题打卡-151215

    UVa 272 - TEX Quotes 水题。字符替换。 UVa 10082 - WERTYU 第一次提交WA,...

  • 次小生成树

    最小生成树大家都会,但是次小生成树呢?生成树算法在计算机运用广泛啊!!!!先来讲一下定义:设 是连通的无向图, 是...

  • 树型DFS 字典树

    给定若干字符串,输出两两strcmp比较的时候每一次比较了多少次 UVA 11732题目链接https://uva...

  • 最小生成树第三弹“克鲁斯卡尔(Kruskal)算法”

    距离上一次分享最小生成树算法,已经过去1个多月。今天,小编重新来分享下另外一个有关的最小生成树算法,也就是“克鲁斯...

  • 素数练习题

    UVA 10375 UVA 10791 UVA10375 Choose and divide 题解 先素数打表,然...

  • 生成树

    次小生成树: 可以用Prim算法先把i点到j点的最大边权值和最小生成树的权值求出来,再对最小生成树加边cost...

  • 经典树与图论(最小生成树、哈夫曼树、最短路径问题---Dijks

    算法导论--最小生成树 最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。 1.Kr...

网友评论

      本文标题:次小生成树 UVA --- 10462

      本文链接:https://www.haomeiwen.com/subject/jevaottx.html