• Oil Deal(最大生成树)


    ZOJ Problem Set - 2677
    Oil Deal

    Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge

    Oil is a very important strategic resource. Recently United Statesof Antarctica invaded the rich in oil country of Qari, and now tryto keep the control of the oil transportation system. The systemconsists of pipelines that connect different nodes --- oil sources andmain country cities and ports. It is designed in such a way thatit is possible to transport oil from any node to any other one.

    However the resisting native forces of Qari are not satisfied withthe situation. So they continuously perform terroracts, blowing up some oil pipelines. Recently terrorists havedecided to perform a series of explosions and want to hurtthe oil pipeline system as much as possible.

    For each pipeline the terrorists know the cost of blowing it up.They have a fixed sum of money and want to explode as many pipesas possible for this sum. However, since they still needoil for themselves in different regions of the country, they wantthe system still be able to transport oil from any node to any otherone. Help them to find out which pipes to blow up.

    Input

    There are several test cases in the input. The first line of each case contains n --- the number of nodes,m --- the number of pipelines, and s --- the amount of moneyterrorists have (2 <= n <= 50,000 , 1 <= m <= 100,000 ,0 <= s <= 1018 ). The following m lines contain informationabout pipelines --- for each pipeline the nodes it connectsand the cost of blowing it up is specified (cost does not exceed 109 ).

    Oil can be transported along each pipeline in both directions, each two nodes are connected by at most one pipeline.

    There is an empty line between cases.

    Output

    On the first line of each case print the maximal numberof pipelines terrorists can blow up. On the second line printthe numbers of these pipelines (pipelines are numbered startingwith 1 as they are listed in the input file).There should be an empty line between cases.

    Example

    Input Output
    6 7 10
    1 2 3
    1 3 3
    2 3 3
    3 4 1
    4 5 5
    5 6 4
    4 6 5
    
    2
    1 5
    

    Source: Andrew Stankevich's Contest #8
    Submit    Status

    先求原图的一棵最大生成树,树中的管道不能被破坏,对于不在树中的管道,在总耗费不超过S的前提下选择被破坏的管道。
    这题本身不难,但是题意很模糊。有以下几点需要注意
    1.s和破坏每个管道的cost都是整数,注意s需用64位;
    2.可以被破坏的管道数量可以是0,在此情况下依然要输出一个空行。
    3.对于一组输入数据,答案不唯一,输出其一即可。

    AC Code:
     1 #include <iostream>
     2 #include <string>
     3 #include <cstdio>
     4 #include <cmath>
     5 #include <cstring>
     6 #include <algorithm>
     7 #include <map>
     8 #include <vector>
     9 #include <queue>
    10 #include <stack>
    11 #define LL long long
    12 #define MAXI 2147483647
    13 #define MAXL 9223372036854775807
    14 #define eps (1e-8)
    15 #define dg(i) cout << "*" << i << endl;
    16 
    17 using namespace std;
    18 
    19 struct Edge
    20 {
    21     int id;
    22     int u, v;
    23     int cost;
    24     bool tag;  //tag == 1: to be exploded
    25 }e[100005];
    26 int set[50005];
    27 
    28 int FindSet(int x)
    29 {
    30     if(x != set[x]) return set[x] = FindSet(set[x]);
    31     return x;
    32 }
    33 
    34 bool operator < (const Edge& x, const Edge& y)
    35 {
    36     return x.cost > y.cost;
    37 }
    38 
    39 int main()
    40 {
    41     int n, m, cnt;
    42     long long s;
    43     vector<int> ans;
    44     bool blank = 0;
    45     while(scanf("%d %d %lld", &n, &m, &s) != EOF)
    46     {
    47         if(blank) puts("");
    48         else blank = 1;
    49         while(!ans.empty()) ans.pop_back();
    50         for(int i = 1; i <= n; i++) set[i] = i;
    51         for(int i = 1; i <= m; i++)
    52         {
    53             scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].cost);
    54             e[i].id = i;
    55             e[i].tag = 1;
    56         }
    57         sort(e + 1, e + 1 + m);
    58         cnt = 0;  //记录最大生成树中已有的边数
    59         for(int i = 1; cnt != n - 1; ++i)
    60         {
    61             int Set_v = FindSet(e[i].v);
    62             int Set_u = FindSet(e[i].u);
    63             if(Set_u != Set_v)
    64             {
    65                 if(Set_u > Set_v) set[Set_u] = Set_v;
    66                 else set[Set_v] = Set_u;
    67                 cnt++;
    68                 e[i].tag = 0;  //更改标记
    69             }
    70         }
    71         for(int i = m; i > 0; i--)
    72         {
    73             if(e[i].tag)
    74             {
    75                 if(s >= e[i].cost) s -= e[i].cost;
    76                 else break;
    77                 ans.push_back(e[i].id);
    78             }
    79         }
    80         printf("%d\n", ans.size());
    81         if(!ans.empty())  //注意必须在ans不为空的情况下执行,否则非法访问内存
    82         {
    83             vector<int>::iterator it = ans.begin();
    84             printf("%d",*it);
    85             for(it++; it != ans.end(); it++)
    86                 printf(" %d", *it);
    87         }
    88         printf("\n");  //就算ans为空也要输出一个空行
    89     }
    90     return 0;
    91 }

      


  • 相关阅读:
    es6 简介
    npm 快速开发技巧
    css清除浮动方法
    mui 总结
    7种 JS 创建对象的经典方式
    JavaScript 的 this 原理
    使用定时器
    dom 操作及方法
    JavaScript的6种继承方式及其优缺点
    贪吃蛇游戏代码
  • 原文地址:https://www.cnblogs.com/cszlg/p/2910403.html
Copyright © 2020-2023  润新知