zoukankan      html  css  js  c++  java
  • UVA1265Tour Belt(kruskal)

    题意:一个无向带权图,候选方案是至少两个点的连通子图,连通子图里的边权的最小值比边界边的最大值大(边界边是一个点在这个子图里,另一个点不在这个子图里)!.问你所有满足候选方案的子图的顶点个数总和是多少?

    分析:kruskal的思想,先将边权大的连接,然后判断是否满足,,,依次连接即可!

    // File Name: 1265.cpp
    // Author: Zlbing
    // Created Time: 2013/5/31 16:52:09
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    const int MAXN=5000+50;
    
    int n,m;
    struct Edge{
        int u,v,cost;
        bool operator <(const Edge e)const{
            return  cost>e.cost;    
        }
    };
    vector<int>G[MAXN],GG[MAXN];
    vector<Edge> edges,ee;
    int f[MAXN];
    int find(int x)
    {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    int num[MAXN];
    bool check(int x)
    {
        int minn=INF,maxn=0;
        for(int i=1;i<=n;i++)
        {
            int fu=find(i);
            if(fu!=x)continue;
            for(int j=0;j<GG[i].size();j++)
            {
                Edge e=ee[GG[i][j]];
                int v=e.v;
                int fv=find(v);
                if(fv==fu)
                {
                    minn=min(minn,e.cost);
                }
                else{
                    maxn=max(maxn,e.cost);
                }
            }
        }
        if(minn>maxn)return true;
        else return false;
    }
    int kruskal(){
        for(int i=0;i<=n;i++)f[i]=i;
        for(int i=0;i<=n;i++)num[i]=1;
        sort(edges.begin(),edges.end());
        int ans=0;
        for(int i=0;i<m;i++)
        {
            Edge e=edges[i];
            int fu=find(e.u);
            int fv=find(e.v);
            if(fu!=fv)
            {
                f[fu]=fv;
                num[fv]+=num[fu];
                if(check(fv)){
                    ans+=num[fv];
                }            
            }
        }
        return ans;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            REP(i,0,n){
                G[i].clear();
                GG[i].clear();
            }
            edges.clear();
            int a,b,c;
            REP(i,1,m)
            {
                scanf("%d%d%d",&a,&b,&c);
                edges.push_back((Edge){a,b,c});
                int mm=edges.size();
                G[a].push_back(mm-1);
                ee.push_back((Edge){a,b,c});
                ee.push_back((Edge){b,a,c});
                mm=ee.size();
                GG[a].push_back(mm-2);
                GG[b].push_back(mm-1);
            }
            int ans=kruskal();
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    centos7之防止root密码被破解
    近期codeforces做题的总结?(不定期更新)
    小程序分享微信好友
    小程序自定义头部导航栏滑动颜色渐变
    小白快速上手的react.js教程
    架构型设计模式-同步模式
    仿vue-cli写一个简易的脚手架
    VUE基础知识篇-vue从零开始学VUE
    彻底理解Vue组件间7种方式通信
    设计模式--观察者模式
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3110796.html
Copyright © 2011-2022 走看看