zoukankan      html  css  js  c++  java
  • ZOJ 2677 Oil Deal(最大生成树)

    题意:破坏石油管道,现一直破坏各个管道所要付出的代价,问在有一定money并且要保证剩余的管道为生成树的情况下, 最多能破坏多少个管道,并将他们的编号从小到大输出来

    思路:将边从大到小排序,构造生成树。 接下来最后剩余的不在最大生成树的边,从最小开始在满足条件下依次取即可。

    这里注意: 答案不唯一,输出其中之一即可。

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <stdio.h>
    #include <string>
    #include <queue>
    using namespace std;
    
    int n,m;
    int blank=0;
    long long s;
    int a,b,cost;
    int ans[105000];
    
    //若flag为true,则表明该边在生成树里。
    //no表示该边的序号
    struct Edge{
        int u,v;
        int cost;
        bool flag;
        int no;
        bool operator <(const Edge& temp) const
        {
            return temp.cost<cost;
        }
    }edge[105000];
    
    struct UF{
        int father[55000];
    
        void init(){
            for(int i=1;i<=n;i++){
                father[i]=i;
            }
        }
    
        int find_root(int x){
           if(father[x]!=x)
               father[x]=find_root(father[x]);
           return father[x];
        }
    
        void Union(int fa,int fb){
            father[fb]=fa;
        }
    }uf;
    
    int main()
    {
        while(scanf("%d%d%lld",&n,&m,&s)!=EOF){
              if(blank)
                puts("");
              else
                blank=1;
              for(int i=0;i<m;i++){
                scanf("%d%d%d",&a,&b,&cost);
                edge[i].u=a;
                edge[i].v=b;
                edge[i].cost=cost;
                edge[i].no=i+1;
                edge[i].flag=false;
              }
    
              sort(edge,edge+m);
    
              int counts=0;
              uf.init();
              for(int i=0;i<m;i++){
                int u=edge[i].u;
                int v=edge[i].v;
                int fu=uf.find_root(u);
                int fv=uf.find_root(v);
                if(counts>=n-1)
                    break;
                if(fu!=fv){
                    edge[i].flag=true;
                    uf.Union(fu,fv);
                    counts++;
                }
              }
              int num=0;
              //从最小边权开始
              for(int i=m-1;i>=0;i--){
                if(!edge[i].flag){
                    if(s>=edge[i].cost){
                        s-=edge[i].cost;
                        ans[num]=edge[i].no;
                        num++;
                    }
                    else{
                        break;
                    }
                }
              }
    
              printf("%d
    ",num);
              for(int p=0;p<num;p++){
                    //如果直接按照"%d "格式输出,也会AC
                    if(p==0)
                        printf("%d",ans[p]);
                    else
                        printf(" %d",ans[p]);
              }
              printf("
    ");
            }
        return 0;
    }
  • 相关阅读:
    各大云服务器的对比
    程式上传的功能修改
    如何免费拥有一个聊天机器人
    自学网站大全(值得收藏)
    三菱PLC串口通信的IO控制
    免费下载知网、万方等数据库文档教程
    QT--Android之全配置教程
    QT--Android之Android环境配置
    QT--Android之Java环境配置
    安装纯净的Windows或者Ubuntu系统教程
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3279735.html
Copyright © 2011-2022 走看看