zoukankan      html  css  js  c++  java
  • CSU 1541 There is No Alternative (最小生成树+枚举)

    题目链接:传送门

    题意:

    有n个点。m条边。要使n个点所有连起来且要花费最小。问有哪些边是必需要连的。

     

    分析:

    要使花费最小肯定是做最小生成树。可是题目要求哪些边是必需要用的。我们能够

    这样思考,我们先求一次最小生成树,然后把这些用到的边统计起来,然后依次枚

    举这n-1条边。使他们不能用,然后继续做最小生成树,假设最后求的值和第一次

    不一样的话那么这条边是肯定要连的。

    代码例如以下:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    
    const int maxn = 50010;
    
    struct nod{
        int x,y,val;
        bool operator < (const struct nod &tmp) const{
            return this->val<tmp.val;
        }
    }edge[maxn];
    
    int par[maxn/100],num[maxn/100];
    int id[maxn/100];
    
    int n,m;
    
    void init(){
        for(int i=0;i<=n;i++) par[i]=i,num[i]=1;
    }
    
    int find_par(int x){
        if(x!=par[x]) return par[x]=find_par(par[x]);
        return par[x];
    }
    
    bool Union(int x,int y){
        x=find_par(x);
        y=find_par(y);
        if(x!=y){
            par[y]=x;
            num[x]+=num[y];
            return true;
        }
        return false;
    }
    
    int ans ,cnt,sum1,sum2;
    
    
    void solve(){
        sum1=sum2=0;
        for(int i=0;i<cnt;i++){
            int tmp=0;init();
            for(int j=0;j<m;j++){
                if(j!=id[i]){
                    if(Union(edge[j].x,edge[j].y))
                        tmp+=edge[j].val;
                }
            }
            if(tmp!=ans) sum1++,sum2+=edge[id[i]].val;
        }
        printf("%d %d
    ",sum1,sum2);
    }
    
    int main(){
        while(~scanf("%d%d",&n,&m)){
            init();
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].val);
            }
            sort(edge,edge+m);
            ans=0,cnt=0;
            memset(id,0,sizeof(id));
            for(int i=0;i<m;i++){
                if(Union(edge[i].x,edge[i].y)){
                    ans+=edge[i].val;
                    id[cnt++]=i;
                }
            }
            solve();
        }
        return 0;
    }
    
    /***
    4 4
    1 2 3
    1 3 5
    2 3 3
    2 4 3
    4 4
    1 2 3
    1 3 1
    2 3 3
    2 4 3
    3 3
    1 2 1
    2 3 1
    1 3 1
    ***/
    


     

  • 相关阅读:
    java基础(7)
    log4j日志打印级别动态调整
    前端学习
    windows下 使用vs command tools 和mingw 分别编译 openssl
    收尾作业(3)
    收尾作业(2)
    收尾作业(1)
    收尾作业第一个接口
    图形建模需求
    收尾作业2
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6953234.html
Copyright © 2011-2022 走看看