码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-09-21 14:47:36      阅读:498      评论:0      收藏:0      [点我收藏+]

标签:技术分享   列表   kruskal算法   有序   scanf   space   while   return   mini   

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

标签:技术分享   列表   kruskal算法   有序   scanf   space   while   return   mini   

原文地址:http://www.cnblogs.com/WJQ2017/p/7568268.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!