zoukankan      html  css  js  c++  java
  • 2017江苏省省赛 Roads(全局最小割)

    Roads

    时间限制: 2 Sec  内存限制: 256 MB
    提交: 6  解决: 2
    [提交][状态][讨论版]

    题目描述

    In ICPCCamp, there are n towns conveniently labeled with 1,2,…,n and m bidirectional roads planned to be built. The i-th road will be built between cities ai and bi with cost ci. The builders in ICPCCamp will build the (n−1) roads with the least total cost to connect any of two cities directly or indirectly.

    Bobo, the mayor of ICPCCamp is going to remove some of the roads from the construction plan. He would like to know the minimum number roads to be removed to strictly increases the total cost.

    Note that the total cost is considered as +∞ if no valid (n−1) roads exist after removing. It is also counted as "total cost strictly increases".

    输入

    The input contains zero or more test cases and is terminated by end-of-file. For each test case:
    The first line contains two integers n and m. The i-th of the following m lines contains ai,bi,ci.
    2≤n≤50,n−1≤m≤n2,1≤ai,bi≤n,1≤ci≤109
    Any two cities will be connected if all m roads are built.
    The sum of n does not exceed 103.

    输出

    For each case, output an integer which denotes the result.

    样例输入

    3 3
    1 2 1
    1 3 2
    2 3 3
    3 4
    1 2 1
    1 2 1
    1 3 2
    1 3 3
    3 4
    1 2 1
    1 2 1
    1 3 2
    1 3 2
    4 6
    1 2 1
    1 3 1
    1 4 1
    2 3 1
    2 4 1
    3 4 1
    

    样例输出

    1
    1
    2
    3
    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define met(a,b) memset(a,b,sizeof a)
    #define pb push_back
    #define mp make_pair
    #define rep(i,l,r) for(int i=(l);i<=(r);++i)
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int N = 1e2+50;;
    const int M = 17;
    const int mod = 19260817;
    const int mo=123;
    const double pi= acos(-1.0);
    typedef pair<int,int>pii;
    ll qpow(int x,int qq){ll f=1,p=x;while(qq){if(qq&1)f=f*p%mod;p=1LL*p*p%mod;qq>>=1;}}
    int n,m;
    int fa[N],wage[N],edg[N][N];
    bool vis[N],in_set[N];
    struct man{
         int u,v,w;
         bool operator <(const man &s)const {
             return w<s.w;
         }
    }a[N*N];
    int findFa(int x){
        return fa[x]==x?x:fa[x]=findFa(fa[x]);
    }
    void unionFa(int x,int y){
        if(findFa(x)==findFa(y))return ;
        fa[findFa(x)]=findFa(y);
    }
    int search(int &s,int &t){
        met(vis,false);
        met(wage,0);
        int u,mincut,mx;
        for(int i=1;i<=n;i++){
            u=mx=-1;
            for(int j=1;j<=n;j++){
                if(!in_set[j]&&!vis[j]&&wage[j]>mx)mx=wage[u=j];
            }
            if(u==-1)return mincut;
            vis[u]=true;
            s=t,t=u;
            mincut=mx;
            for(int j=1;j<=n;j++){
                if(!in_set[j]&&!vis[j])wage[j]+=edg[u][j];
            }
        }
        return mincut;
    }
    int stoer_wagner(){
        int  mincut=inf,s,t,ret;
        for(int i=1;i<n;i++){
            ret=search(s,t);
            in_set[t]=true;
            if(ret!=0&&ret<mincut)mincut=ret;//加ret!=0是为了求所有联通块的最小割
            for(int j=1;j<=n;j++)if(!in_set[j])edg[s][j]=(edg[j][s]+=edg[j][t]);
        }
        return mincut;
    }
    int main(){
        while(~scanf("%d%d",&n,&m)){
            for(int i=0;i<=n;i++)fa[i]=i;
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
            }
            sort(a,a+m);
            int ans=inf,cnt=0;
            for(int i=0;i<m;){
                int now=i,w=a[i].w;
                met(edg,0);met(in_set,false);
                for(;a[i].w==w&&i<m;i++){
                    if(findFa(a[i].u)!=findFa(a[i].v)){
                        edg[findFa(a[i].u)][findFa(a[i].v)]++;
                        edg[findFa(a[i].v)][findFa(a[i].u)]++;
                    }
                }
                ans=min(ans,stoer_wagner());
                for(int i=now;a[i].w==w&&i<m;i++){
                    if(findFa(a[i].u)!=findFa(a[i].v)){
                        unionFa(a[i].u,a[i].v);
                        cnt++;
                    }
                }
                if(cnt>=n-1)break;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    剑指前端(前端入门笔记系列)——BOM
    剑指前端(前端入门笔记系列)——DOM(元素大小)
    剑指前端(前端入门笔记系列)——DOM(属性节点)
    剑指前端(前端入门笔记系列)——DOM(元素节点)
    剑指前端(前端入门笔记系列)——Math对象
    剑指前端(前端入门笔记系列)——DOM(基本组成与操作)
    剑指前端(前端入门笔记系列)——数组(方法)
    剑指前端(前端入门笔记系列)——数组(基本语法)
    剑指前端(前端入门笔记系列)——Date对象
    根据不同域名实现数据源切换
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/7488353.html
Copyright © 2011-2022 走看看