Top确实难多了
这道题我是将一开始就连通的路cost改成0,然后对每个陷落的城市,做一次kruskal,统计出最大的代价。
一开始顶点编号写成了0~n - 1,导致很多测试点出错,下次一定要小心,不能再犯这种低级错误了!
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
struct Edge{
int u,v;
int cost;
bool status; // true -> 连通 false -> 不连通
Edge(){}
Edge(int a,int b,int c,int d){
u = a;
v = b;
if(d == 1){
cost = 0;
status = true;
}
else{
cost = c;
status = false;
}
}
};
vector<Edge> edges;
int cost[510];
int pre[510];
int unionSearch(int root){
int son,tmp;
son = root;
while(root != pre[root])
root = pre[root];
while(son != root){
tmp = pre[son];
pre[son] = root;
son = tmp;
}
return root;
}
void join(int root1,int root2){
int x,y;
x = unionSearch(root1);
y = unionSearch(root2);
if(x != y)
pre[x] = y;
}
int kruskal(int k,int n,int m){
int ans = 0,numEdge = 0;
for(int i = 1;i <= n;i++){
pre[i] = i;
}
for(int i = 0;i < m;i++){
int preU = unionSearch(edges[i].u);
int preV = unionSearch(edges[i].v);
if(edges[i].u == k || edges[i].v == k)
continue;
if(preU != preV){ // 如果没有连通,且两个城市均不是陷落的城市
join(preU,preV);
ans += edges[i].cost;
numEdge++;
if(numEdge == n - 2)
break;
}
}
if(numEdge != n - 2)
return INT_MAX;
else
return ans;
}
bool cmp(Edge a,Edge b){
return a.cost < b.cost;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i = 0;i < m;i++){
int u,v;
int cost,status;
scanf("%d%d%d%d",&u,&v,&cost,&status);
edges.push_back(Edge(u,v,cost,status));
}
sort(edges.begin(),edges.end(),cmp);
vector<int> criticalCities;
int maxCost = 0;
for(int i = 1;i <= n;i++){ // 第i个城市陷落后,算cost
cost[i] = kruskal(i,n,m);
if(cost[i] > maxCost){
criticalCities.clear();
criticalCities.push_back(i);
maxCost = cost[i];
}else if(cost[i] == maxCost && maxCost != 0)
criticalCities.push_back(i);
}
for(int i = 0;i < criticalCities.size();i++){
printf("%d",criticalCities[i]);
if(i != criticalCities.size() - 1)
printf(" ");
}
if(criticalCities.size() == 0)
printf("0");
system("pause");
return 0;
}