• vijos:P1190繁忙的都市


    描述

    城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造。城市C的道路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道路相连,两个交叉路口之间最多有一条道路相连接。这些道路是双向的,且把所有的交叉路口直接或间接的连接起来了。每条道路都有一个分值,分值越小表示这个道路越繁忙,越需要进行改造。但是市政府的资金有限,市长希望进行改造的道路越少越好,于是他提出下面的要求:
    1.改造的那些道路能够把所有的交叉路口直接或间接的连通起来。

    2.在满足要求1的情况下,改造的道路尽量少。

    3.在满足要求1、2的情况下,改造的那些道路中分值最大的道路分值尽量小。

    任务:作为市规划局的你,应当作出最佳的决策,选择那些道路应当被修建。

    格式

    输入格式

    第一行有两个整数n,m表示城市有n个交叉路口,m条道路。接下来m行是对每条道路的描述,u, v, c表示交叉路口u和v之间有道路相连,分值为c。(1≤n≤300,1≤c≤10000)

    输出格式

    两个整数s, max,表示你选出了几条道路,分值最大的那条道路的分值是多少。

    输入:

    4 5
    1 2 3
    1 4 5
    2 4 7
    2 3 6
    3 4 8

    输出

    3 6

    思路:求图的所有最小生成树中的最大边的最小值。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int MAXN=10005;
    struct Edge{
        int u,v,w;
    }es[MAXN];
    int n,m;
    bool comp(const Edge &e1,const Edge &e2)
    {
        return e1.w < e2.w;
    }
    int par[305],rnk[305];
    void prep()
    {
        for(int i=0;i<305;i++)
        {
            par[i]=i;
            rnk[i]=0;
        }
    }
    int fnd(int x)
    {
        if(x==par[x])
            return x;
        return par[x]=fnd(par[x]);
    }
    void unite(int u,int v)
    {
        int a=fnd(u);
        int b=fnd(v);
        if(a==b)    return ;
        if(rnk[a]<rnk[b])
        {
            par[a]=b;
        }
        else
        {
            par[b]=a;
            if(rnk[a]==rnk[b])    rnk[a]++;
        }
    }
    bool same(int u,int v)
    {
        return fnd(u)==fnd(v);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].w);
        }
        sort(es,es+m,comp);
        int res=INF;
        
        for(int i=0;i<m;i++)
        {
            int cnt=0;
            int mx=-1;
            prep();
            for(int j=i;j<m;j++)
            {
                if(!same(es[j].u,es[j].v))
                {
                    unite(es[j].u,es[j].v);
                    cnt++;
                    mx=max(es[j].w,mx);
                }
            }
            if(cnt==n-1)
            {
                res=min(res,mx);
            }
        }
        printf("%d %d
    ",n-1,res);
        return 0;
    }    

    其实,利用树的特点可得就是求做小生成树中的最大边

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXN=10005;
    struct Edge{
        int u,v,w;
    }es[MAXN];
    int n,m;
    bool comp(const Edge &e1,const Edge &e2)
    {
        return e1.w < e2.w;
    }
    int par[305],rnk[305];
    void prep()
    {
        for(int i=0;i<305;i++)
        {
            par[i]=i;
            rnk[i]=0;
        }
    }
    int fnd(int x)
    {
        if(x==par[x])
            return x;
        return par[x]=fnd(par[x]);
    }
    void unite(int u,int v)
    {
        int a=fnd(u);
        int b=fnd(v);
        if(a==b)    return ;
        if(rnk[a]<rnk[b])
        {
            par[a]=b;
        }
        else
        {
            par[b]=a;
            if(rnk[a]==rnk[b])    rnk[a]++;
        }
    }
    bool same(int u,int v)
    {
        return fnd(u)==fnd(v);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].w);
        }
        sort(es,es+m,comp);
        prep();
        int mx=-1;
        for(int i=0;i<m;i++)
        {
            if(!same(es[i].u,es[i].v))
            {
                unite(es[i].u,es[i].v);
                mx=max(es[i].w,mx);
            }
        }
        printf("%d %d
    ",n-1,mx);
        return 0;
    }    
  • 相关阅读:
    PHPCMS的自增长标签
    discuz!X2头像无法显示解决方法
    屏蔽“您目前使用的Discuz!程序有新版本发布,请及时升级!”提示
    python +Django 搭建web开发环境初步,显示当前时间
    Java之美[从菜鸟到高手演变]之设计模式四
    Java之美[从菜鸟到高手演变]之设计模式三
    Java之美[从菜鸟到高手演变]之设计模式二
    Java开发中的23种设计模式详解
    Cglib动态代理
    JSP 对象的作用范围
  • 原文地址:https://www.cnblogs.com/program-ccc/p/5359530.html
Copyright © 2020-2023  润新知