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

It is vitally important to have all the cities connected by highways in a war. If a city is conquered by the enemy, all the highways from/toward that city will be closed. To keep the rest of the cities connected, we must repair some highways with the minimum cost. On the other hand, if losing a city will cost us too much to rebuild the connection, we must pay more attention to that city.

Given the map of cities which have all the destroyed and remaining highways marked, you are supposed to point out the city to which we must pay the most attention.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 2 numbers N (≤500), and M, which are the total number of cities, and the number of highways, respectively. Then M lines follow, each describes a highway by 4 integers: City1 City2 Cost Status where City1 and City2 are the numbers of the cities the highway connects (the cities are numbered from 1 to N), Cost is the effort taken to repair that highway if necessary, and Status is either 0, meaning that highway is destroyed, or 1, meaning that highway is in use.

Note: It is guaranteed that the whole country was connected before the war.

Output Specification:

For each test case, just print in a line the city we must protest the most, that is, it will take us the maximum effort to rebuild the connection if that city is conquered by the enemy.

In case there is more than one city to be printed, output them in increasing order of the city numbers, separated by one space, but no extra space at the end of the line. In case there is no need to repair any highway at all, simply output 0.

Sample Input 1:

4 5
1 2 1 1
1 3 1 1
2 3 1 0
2 4 1 1
3 4 1 0

Sample Output 1:

1 2

Sample Input 2:

4 5
1 2 1 1
1 3 1 1
2 3 1 0
2 4 1 1
3 4 2 1

Sample Output 2:

0

pat的题目真实坑爹啊,数据范围都不明确!!!!直接用并查集求最小生成树,把边分成两类,一类是已有的边,代价为0,一类是要修复的边,代价就是修复的代价,然后每次暴力枚举删除哪个电以后求剩下n-1个的最小生成树。  注意这里有一种特殊情况,即如果删除某个点以后无法让剩下n-1个点联通,那么此时的修复代价是最大的,而题目并没有明确这一点。 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int const N=500+10;
 4 struct edge{
 5     int x,y,z;
 6     bool operator < (const edge &rhs)const{
 7         return z<rhs.z;
 8     }
 9 }e[N*N],e2[N*N];
10 int n,m,f[N],ans[N];
11 int find(int x){
12     return x==f[x]? x:f[x]=find(f[x]);
13 }
14 int main(){
15     scanf("%d%d",&n,&m);
16     int n1=0,n2=0;
17     for(int i=1;i<=m;i++){
18         int x,y,z,s;
19         scanf("%d%d%d%d",&x,&y,&z,&s);
20         if(s==1) {
21             n1++;
22             e[n1]=(edge){x,y,0};
23         }else {
24             n2++;
25             e2[n2]=(edge){x,y,z};
26         }
27     }
28     sort(e+1,e+n1+1);
29     sort(e2+1,e2+n2+1);
30     int cost=-1000000;
31     for(int k=1;k<=n;k++){
32         for(int i=1;i<=n;i++) f[i]=i;
33         int   sum=0,c=0;
34         for(int i=1;i<=n1;i++){
35             if(e[i].x==k || e[i].y==k) continue;
36             int fx=find(e[i].x);
37             int fy=find(e[i].y);
38             if(fx!=fy){
39                 sum++;
40                 f[fx]=fy;
41             }
42         }
43         for(int i=1;i<=n2 && sum<n-2;i++){
44             if(e2[i].x==k || e2[i].y==k) continue;
45             int fx=find(e2[i].x);
46             int fy=find(e2[i].y);
47             if(fx!=fy){
48                 sum++;
49                 f[fx]=fy;
50                 c+=e2[i].z;
51             }
52         }
53         if(sum<n-2) c=1e9;
54         if(c>cost){
55             ans[0]=1; ans[1]=k;cost=c;
56         }else if(c==cost){
57             ans[++ans[0]]=k;
58         }
59     }
60     if(cost==0){
61         printf("%d\n",0);
62     }else {
63         printf("%d",ans[1]);
64         for(int i=2;i<=ans[0];i++)
65             printf(" %d",ans[i]);
66     }
67     return 0;
68 }

 

原文地址:https://www.cnblogs.com/ZJXXCN/p/11504852.html

时间: 2024-11-07 05:13:10

pat 顶级 1001 Battle Over Cities - Hard Version (35 分)的相关文章

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

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

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

这个题的题意是假设某个城市被占领后,要使剩下的城市保持联通可能会花钱修路,求最小花费里花费最多的那个被占领的城市. 这个题凭感觉就是最小生成树,最小生成树满足权值最小(最小花费),所以依次去掉某个城市的所有与其相接的路径,把剩下的路加入最小生成树,求最大值即可. 有一个地方写的时候没注意到,就是去掉某个城市后可能导致连通块的数量的增多,这种情况下算这个城市的花费无限大就可以了(自己真菜QAQ). #include <iostream> #include <cstdio> #incl

PAT Advanced Level 1013 Battle Over Cities (25)(25 分)

1013 Battle Over Cities (25)(25 分) It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any

PAT 甲级 1013 Battle Over Cities (25 分)(图的遍历,统计强连通分量个数,bfs,一遍就ac啦)

1013 Battle Over Cities (25 分) It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any oth

PAT 甲级 1001 A+B Format (20)(20 分)

1001 A+B Format (20)(20 分) Calculate a + b and output the sum in standard format -- that is, the digits must be separated into groups of three by commas (unless there are less than four digits). Input Each input file contains one test case. Each case

PAT Advanced 1013 Battle Over Cities (25分)

It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of

PAT 甲级 1013 Battle Over Cities

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #define MAX 1001 5 int a[MAX][MAX]; 6 int visited[MAX]; 7 int n, m, k; 8 9 using namespace std; 10 11 int dfs(int x) 12 { 13 visited[x]=1; 14 for (int i=1; i<=n; i++) 15

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

/**题目:删去一个点,然后求出需要增加最小代价的边集合生成连通图思路:prim+最小堆1.之前图中未破坏的边必用,从而把两两之间可互达的点集合 合并成一个点2.求出不同点集合的最短距离,用prim+最小堆求出最小生成树 kruskal1.之前图中未破坏的边必用,全部加到图中2.途中被破坏的边按照边权从小到大的顺序依次加入图中,直到图变为连通图 两个方法的对应一个点的最小生成树的复杂度都是nlogm,第二个方法较好写 优化:1.未破坏的边直接加入图中2.当有n-2条边(当前删去一个点后,图中n-

PAT:1013. Battle Over Cities (25) AC

#include<stdio.h> #include<string.h> #include<vector> using namespace std; const int MAX=1010; int n,m,k; //城市数,高速公路数,查询次数 int DELETE; //要删除的点 vector<int> ADJ[MAX]; //邻接表 bool vis[MAX]; void DFS(int s) { if(DELETE==s) return; //表示该