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

 //#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <vector> using namespace std; struct edge { // edge struct
int u, v, cost;
};
vector<edge> edges; // the number of edges is greater than 500 far and away int cmp(edge a, edge b) { // sort rule
return a.cost < b.cost;
} int parent[]; // union-find set void initParent(int n) { // initialize union-find set
int i;
for(i = ; i <= n; i++) {
parent[i] = -; // a minus means it is a root node and its absolute value represents the number of the set
}
} int findRoot(int x) { // find the root of the set
int s = x;
while(parent[s] > ) {
s = parent[s];
} int temp;
while(s != x) { // compress paths for fast lookup
temp = parent[x];
parent[x] = s;
x = temp;
} return s;
} void unionSet(int r1, int r2) { // union sets. More concretely, merge a small number of set into a large collection
int sum = parent[r1] + parent[r2];
if(parent[r1] > parent[r2]) {
parent[r1] = r2;
parent[r2] = sum;
} else {
parent[r2] = r1;
parent[r1] = sum;
}
} int maxw = ; // max cost
bool infw; // infinite cost int kruskal(int n, int m, int out) { // Kruskal algorithm to get minimum spanning tree
initParent(n); int u, v, r1, r2, num = , i, w = ;
for (i = ; i < m; i++) {
u = edges[i].u;
v = edges[i].v; if (u == out || v == out) {
continue;
} r1 = findRoot(u);
r2 = findRoot(v); if (r1 != r2) {
unionSet(r1, r2);
num++; if (edges[i].cost > ) { // only consider the cost which is not zero
w += edges[i].cost;
} if (num == n - ) {
break;
}
}
} //printf("num %d\n", num);
if (num < n - ) { // spanning tree is not connected
w = -; // distinguish the situation of the occurrence of infinite cost if (!infw) { // when infinite cost first comes out
infw = true;
}
} return w;
} int main() {
int n, m;
scanf("%d%d", &n, &m); int i, status;
edge e;
for (i = ; i < m; i++) {
scanf("%d%d%d%d", &e.u, &e.v, &e.cost, &status);
if (status == ) {
e.cost = ;
} edges.push_back(e);
} if (m > ) {
sort(edges.begin(), edges.end(), cmp);
} int curw, res[], index = ;
for (i = ; i <= n; i++) { // traverse all vertices to obtain the target vertex
curw = kruskal(n, m, i);
if (!infw) { // when infinite cost doesn't come out
if (curw < maxw) {
continue;
} if (curw > maxw) {
index = ;
maxw = curw;
}
res[index++] = i;
} else { // otherwise
if (curw < ) {
if (maxw > ) {
maxw = -;
index = ;
} res[index++] = i;
}
}
} if (index > ) {
for (i = ; i < index; i++) {
if (i > ) {
printf(" ");
}
printf("%d", res[i]);
}
} else {
printf("");
}
printf("\n"); system("pause");
return ;
}

  

  参考资料

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

PAT-Top1001. Battle Over Cities - Hard Version (35)的更多相关文章

  1. PAT 1013 Battle Over Cities

    1013 Battle Over Cities (25 分)   It is vitally important to have all the cities connected by highway ...

  2. PAT 1013 Battle Over Cities(并查集)

    1013. Battle Over Cities (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue It ...

  3. pat 1013 Battle Over Cities(25 分) (并查集)

    1013 Battle Over Cities(25 分) It is vitally important to have all the cities connected by highways i ...

  4. PAT 1013 Battle Over Cities (dfs求连通分量)

    It is vitally important to have all the cities connected by highways in a war. If a city is occupied ...

  5. PAT A1013 Battle Over Cities (25 分)——图遍历,联通块个数

    It is vitally important to have all the cities connected by highways in a war. If a city is occupied ...

  6. PAT 1013 Battle Over Cities DFS深搜

    It is vitally important to have all the cities connected by highways in a war. If a city is occupied ...

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

    /**题目:删去一个点,然后求出需要增加最小代价的边集合生成连通图思路:prim+最小堆1.之前图中未破坏的边必用,从而把两两之间可互达的点集合 合并成一个点2.求出不同点集合的最短距离,用prim+ ...

  8. 「日常训练」Battle Over Cities - Hard Version(PAT-TOP-1001)

    题意与分析 题意真的很简单,实在不想讲了,简单说下做法吧. 枚举删除每个点,然后求最小生成树,如果这个路已经存在那么边权就是0,否则按照原来的处理,之后求花费,然后判整个图是否联通(并查集有几个roo ...

  9. PAT_A1013#Battle Over Cities

    Source: PAT A1013 Battle Over Cities (25 分) Description: It is vitally important to have all the cit ...

随机推荐

  1. base | Tread类

    Tread类 Linux中,每个进程有一个pid,类型pid_t,由getpid()取得.Linux下的POSIX线程也有一个id,类型 pthread_t,由pthread_self()取得,该id ...

  2. Elasticsearch和HDFS 容错机制 备忘

    1.Elasticsearch 横向扩容以及容错机制http://www.bubuko.com/infodetail-2499254.html 2.HDFS容错机制详解https://www.cnbl ...

  3. Visual Studio "14" CTPs

    下载地址:http://www.visualstudio.com/en-us/downloads/visual-studio-14-ctp-vs       上张有亮点的图: 实现亮点的方法(Remo ...

  4. cuda by example【读书笔记2】

    常量内存 用常量内存来替换全局内存可以有效的减少内存带宽 __constant__修饰符标识常量内存,从主机内存复制到GPU上的常量内存时,需要特殊版本的cudaMemcpy(): cudaMemcp ...

  5. java进阶书籍推荐(不包括基础)

    个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他资料 对着书上的代码自己敲的时候方便 “看完书之后再次提升自我的最好途径是看一 ...

  6. python全栈开发day74-普通验证码和滑块验证码

    一.昨日内容回顾 django认证系统 1. 默认auth_user ``` # 创建用户 from django.contrib.auth.models import User User.objec ...

  7. ionic2+集成第三方sdk时,合并多个清单文件的方法

    具体方案android studio官网上已经给出,但需要架梯子,所以这篇文章直接把它搬到墙内,方便查看: 合并多个清单文件 合并优先级 合并冲突启发式算法 合并规则标记 节点标记 属性标记 标记选择 ...

  8. js+jquery手写弹出提示框

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. JavaScript 组数去重demo

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  10. u盘系统安装步骤

    应今天Webcast听众的要求,写一写从U盘安装Windows 7的必要步骤.步骤一:准备U盘   把容量在4GB以上的U盘插入计算机,在命令行运行下列命令,完成U盘的分区格式化.   diskpar ...