PAT-Top1001. Battle Over Cities - Hard Version (35)

Posted 王景迁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT-Top1001. Battle Over Cities - Hard Version (35)相关的知识,希望对你有一定的参考价值。

  在敌人占领之前由城市和公路构成的图是连通图。在敌人占领某个城市之后所有通往这个城市的公路就会被破坏,接下来可能需要修复一些其他被毁坏的公路使得剩下的城市能够互通。修复的代价越大,意味着这个城市越重要。如果剩下的城市无法互通,则说明代价无限大,这个城市至关重要。最后输出的是代价最大的城市序号有序列表。借助并查集和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\\n", 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("\\n");
152 
153     system("pause");
154     return 0;
155 }
View Code

 

  

 

  参考资料

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

以上是关于PAT-Top1001. Battle Over Cities - Hard Version (35)的主要内容,如果未能解决你的问题,请参考以下文章

pat 顶级 1001 Battle Over Cities - Hard Version (35 分)

PAT顶1001 Battle Over Cities - Hard Version (35 分) Kruskal求最小生成树

PAT T1001 Battle Over Cities-Hard Version

pat1001. Battle Over Cities - Hard Version 解题报告

PAT1013. Battle Over Cities(邻接矩阵邻接表分别dfs)

1013. Battle Over Cities (25)