zoukankan      html  css  js  c++  java
  • 2018"百度之星"程序设计大赛

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=6349

    题目

    三原色图

    Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 555    Accepted Submission(s): 186


    Problem Description
    度度熊有一张 n 个点 m 条边的无向图,所有点按照 1,2,,n 标号,每条边有一个正整数权值以及一种色光三原色红、绿、蓝之一的颜色。

    现在度度熊想选出恰好 k 条边,满足只用这 k 条边之中的红色边和绿色边就能使 n 个点之间两两连通,或者只用这 k 条边之中的蓝色边和绿色边就能使 n 个点之间两两连通,这里两个点连通是指从一个点出发沿着边可以走到另一个点。

    对于每个 k=1,2,,m ,你都需要帮度度熊计算选出恰好 k 条满足条件的边的权值之和的最小值。
     
    Input
    第一行包含一个正整数 T ,表示有 T 组测试数据。

    接下来依次描述 T 组测试数据。对于每组测试数据:

    第一行包含两个整数 nm ,表示图的点数和边数。

    接下来 m 行,每行包含三个整数 a,b,w 和一个字符 c ,表示有一条连接点 a 与点 b 的权值为 w 、颜色为 c 的无向边。

    保证 1T1001n,m1001a,bn1w1000c{R,G,B} ,这里 R,G,B 分别表示红色、绿色和蓝色。
     
    Output
    对于每组测试数据,先输出一行信息 "Case #x:"(不含引号),其中 x 表示这是第 x 组测试数据,接下来 m 行,每行包含一个整数,第 i 行的整数表示选出恰好 i 条满足条件的边的权值之和的最小值,如果不存在合法方案,输出 1 ,行末不要有多余空格。
     
    Sample Input
    1 5 8 1 5 1 R 2 1 2 R 5 4 5 R 4 5 3 G 1 3 3 G 4 3 5 G 5 4 1 B 1 2 2 B
     
    Sample Output
    Case #1: -1 -1 -1 9 10 12 17 22
     
    解题思路:采用克鲁斯卡尔算法,构建最小生成树,边数小于n-1,无法构成所以答案为-1,如果可以构成的话,必定需要花费了n-1条边,对于剩下的n~m条边,参考大佬博客的做法,我们可以把它们放到一个从小到大排列的优先队列里,这样我们只要每次讲队首元素加入到答案,则出队即可。只需要跑两次克鲁斯卡尔,取答案的最小值就可以了。
     
    这里也挺需要特别注意无法构成最小生成树的情况,答案全部为-1,我开始就在这WA了。
     
    附上代码:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define maxn 105
    #define inf 0x3f3f3f3f
    priority_queue<int,vector<int>,greater<int> >que;
    int n,m,par[maxn],rk[maxn],ans[maxn];
    struct node{
        int u,v,w,c;
        bool operator<(const node &a)const
        {  //按边的权值从小到大排 
            return w<a.w;
        }
    }edge[maxn]; //边数组 
    void init()
    {  //初始化 
        for(int i=1;i<=n;i++)
        {
            par[i]=i;
            rk[i]=0;
        }
    }
    int find(int x)
    {  //查找节点x所在树的根节点 
        if(x==par[x])
            return x;
        else //路径压缩 
            return par[x]=find(par[x]);
    }
    void unite(int x,int y)
    {  //将两个不同集合的节点合并,两个集合变一个 
        int fx=find(x),fy=find(y);
        if(rk[fx]<rk[fy])
            par[fx]=fy;
        else
        {
            par[fy]=fx;
            if(rk[fx]==rk[fy])
                rk[fx]++;
        }
    }
    void kruskal(int c)
    {
        int cnt=0,sum=0;  //cnt已选边的数目,sum为当前边权值之和 
        init();
        while(!que.empty())
            que.pop();
        for(int i=0;i<m;i++)
        {
            int u=edge[i].u,v=edge[i].v,col=edge[i].c;
            if(find(u)!=find(v)&&col!=c&&cnt<=n-1)
            {
                sum+=edge[i].w;
                cnt++;
                unite(u,v);
                if(cnt==n-1)
                {
                    if(ans[cnt]==-1) ans[cnt]=sum;
                    else ans[cnt]=min(ans[cnt],sum);
                }
            }
            else  //将未选中的边加入优先队列 
                que.push(edge[i].w);
        }
        if(cnt<n-1) return;
        while(!que.empty())
        {
            sum+=que.top();
            que.pop();
            ++cnt;
            if(ans[cnt]==-1) ans[cnt]=sum;
            else ans[cnt]=min(ans[cnt],sum);
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        int kase=0;
        while(T--)
        {
            scanf("%d%d",&n,&m);
            char c;
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
                getchar();
                c=getchar();
                if(c=='B') edge[i].c=0;
                else if(c=='R') edge[i].c=1;
                else edge[i].c=2;
            }
            memset(ans,-1,sizeof(ans));
            sort(edge,edge+m);
            kruskal(0);  //第一种方案颜色不可为蓝色 
            kruskal(1);  //第二种方案颜色不可为红色 
            printf("Case #%d:
    ",++kase);
            for(int i=1;i<=m;i++)
                printf("%d
    ",ans[i]);
        }
    }
  • 相关阅读:
    rsync
    SAMBA服务搭建
    top,job,user,file,alias
    FTP服务搭建
    shell_script2
    shell_script1
    shell_processing
    shell_advanced
    shell_basic
    docker搭建私有仓库遇到的坑 http: server gave HTTP response to HTTPS client
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/9724920.html
Copyright © 2011-2022 走看看