• PAT-Top1001. Battle Over Cities


      在敌人占领之前由城市和公路构成的图是连通图。在敌人占领某个城市之后所有通往这个城市的公路就会被破坏,接下来可能需要修复一些其他被毁坏的公路使得剩下的城市能够互通。修复的代价越大,意味着这个城市越重要。如果剩下的城市无法互通,则说明代价无限大,这个城市至关重要。最后输出的是代价最大的城市序号有序列表。借助并查集和Kruskal算法(最小生成树算法)来解决这个问题。

     

      1 //#include "stdafx.h"
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <vector>
      5 
      6 using namespace std;
      7 
      8 struct edge { // edge struct
      9     int u, v, cost;
     10 };
     11 vector<edge> edges; // the number of edges is greater than 500 far and away
     12 
     13 int cmp(edge a, edge b) { // sort rule
     14     return a.cost < b.cost;
     15 }
     16 
     17 int parent[510]; // union-find set
     18 
     19 void initParent(int n) { // initialize union-find set
     20     int i;
     21     for(i = 1; i <= n; i++) {
     22         parent[i] = -1; // a minus means it is a root node and its absolute value represents the number of the set
     23     }
     24 }
     25 
     26 int findRoot(int x) { // find the root of the set
     27     int s = x;
     28     while(parent[s] > 0) {
     29         s = parent[s];
     30     }
     31 
     32     int temp;
     33     while(s != x) { // compress paths for fast lookup
     34         temp = parent[x];
     35         parent[x] = s;
     36         x = temp;
     37     }
     38 
     39     return s;
     40 }
     41 
     42 void unionSet(int r1, int r2) { // union sets. More concretely, merge a small number of set into a large collection
     43     int sum = parent[r1] + parent[r2];
     44     if(parent[r1] > parent[r2]) { 
     45         parent[r1] = r2;
     46         parent[r2] = sum;
     47     } else {
     48         parent[r2] = r1;
     49         parent[r1] = sum;
     50     }
     51 }
     52 
     53 int maxw = 1; // max cost
     54 bool infw; // infinite cost
     55 
     56 int kruskal(int n, int m, int out) { // Kruskal algorithm to get minimum spanning tree
     57     initParent(n);
     58 
     59     int u, v, r1, r2, num = 0, i, w = 0;
     60     for (i = 0; i < m; i++) {
     61         u = edges[i].u;
     62         v = edges[i].v;
     63 
     64         if (u == out || v == out) {
     65             continue;
     66         }
     67 
     68         r1 = findRoot(u);
     69         r2 = findRoot(v);
     70 
     71         if (r1 != r2) {
     72             unionSet(r1, r2);
     73             num++;
     74 
     75             if (edges[i].cost > 0) { // only consider the cost which is not zero
     76                 w += edges[i].cost;
     77             }
     78 
     79             if (num == n - 2) {
     80                 break;
     81             }
     82         }
     83     }
     84 
     85     //printf("num %d
    ", num);
     86     if (num < n - 2) { // spanning tree is not connected
     87         w = -1; // distinguish the situation of the occurrence of infinite cost
     88 
     89         if (!infw) { // when infinite cost first comes out
     90             infw = true;
     91         }
     92     }
     93 
     94     return w;
     95 }
     96 
     97 int main() {
     98     int n, m;
     99     scanf("%d%d", &n, &m);
    100 
    101     int i, status;
    102     edge e;
    103     for (i = 0; i < m; i++) {
    104         scanf("%d%d%d%d", &e.u, &e.v, &e.cost, &status);
    105         if (status == 1) {
    106             e.cost = 0;
    107         }
    108 
    109         edges.push_back(e);
    110     }
    111 
    112     if (m > 0) {
    113         sort(edges.begin(), edges.end(), cmp);
    114     }
    115 
    116     int curw, res[510], index = 0;
    117     for (i = 1; i <= n; i++) { // traverse all vertices to obtain the target vertex
    118         curw = kruskal(n, m, i);
    119         if (!infw) { // when infinite cost doesn't come out
    120             if (curw < maxw) {
    121                 continue;
    122             }
    123 
    124             if (curw > maxw) {
    125                 index = 0;
    126                 maxw = curw;
    127             } 
    128             res[index++] = i;
    129         } else { // otherwise
    130             if (curw < 0) {
    131                 if (maxw > 0) {
    132                     maxw = -1;
    133                     index = 0;
    134                 } 
    135 
    136                 res[index++] = i;
    137             }
    138         }
    139     }
    140 
    141     if (index > 0) {
    142         for (i = 0; i < index; i++) {
    143             if (i > 0) {
    144                 printf(" ");
    145             } 
    146             printf("%d", res[i]);
    147         }
    148     } else {
    149         printf("0");
    150     }
    151     printf("
    ");
    152 
    153     system("pause");
    154     return 0;
    155 }
    View Code

     

      

     

      参考资料

           pat-top 1001. Battle Over Cities - Hard Version (35)

  • 相关阅读:
    Systemverilog for design 笔记(三)
    SystemVerilog for design 笔记(二)
    Systemverilog for design 笔记(一)
    假如m是奇数,且m>=3,证明m(m² -1)能被8整除
    SharpSvn操作 -- 获取Commit节点列表
    GetRelativePath获取相对路径
    Dictionary(支持 XML 序列化),注意C#中原生的Dictionary类是无法进行Xml序列化的
    Winform中Checkbox与其他集合列表类型之间进行关联
    Image(支持 XML 序列化),注意C#中原生的Image类是无法进行Xml序列化的
    修复使用<code>XmlDocument</code>加载含有DOCTYPE的Xml时,加载后增加“[]”字符的错误
  • 原文地址:https://www.cnblogs.com/WJQ2017/p/7568268.html
Copyright © 2020-2023  润新知