题意:
战争年代,公路对于两个城市的连接是至关重要的。现在有一个图,存在n个城市,m条路,每条路有个修建的费用weight,有一个标记位status表示这条是否被破坏,没有破坏的路,无需修建,无花费。现在这个图上的每个城市可能被破坏,破坏的城市,所有和他联通的路都不能通行,找一个方法把剩余城市连接起来,可能需要修路,修路有最小代价,而现在需要找出最需要保护的城市,保护其不被破坏。(最小代价中最大代价的城市需要保护)
方法:
使用并查集,最小中最大,
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
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct road{
int city1,city2,weight,status;
};
const int MAX = 10000000;
const int M = 500 * 499;
int cmp(const void *r1,const void *r2);
int findroot(int cityset[],int index);
int unionset(int cityset[],int index1,int index2);
int main(void)
{
int n,m,i,j,usecnt = 0,destcnt = 0;
road tmp;
road *use, *destroyed;
use = new road[M];
destroyed = new road[M];
scanf("%d %d",&n,&m);
for(i = 0; i < m; i++)
{
scanf("%d %d %d %d", &tmp.city1, &tmp.city2, &tmp.weight, &tmp.status);
if(tmp.status){
use[usecnt++] = tmp;
}
else {
destroyed[destcnt++] = tmp;
}
}
qsort(destroyed, destcnt, sizeof(road), cmp);
int *cityset = new int[n + 1];
set<int> pro;
int max_cost = 0, cnt, cost;
for(i = 1; i< n + 1; i++)
{
for(j = 0;j<n+1;j++)
{
cityset[j]=-1;
}
cnt = cost = 0;
for(j=0;j<usecnt&&cnt!=-n+1;j++)
{
if(use[j].city1==i||use[j].city2==i)
{
continue;
}
int index = unionset(cityset,use[j].city1,use[j].city2);
if(index>0&&cityset[index]<cnt)
{
cnt = cityset[index];
}
}
for(j=0;j<destcnt&&cnt!=-n+1;j++)
{
if(destroyed[j].city1==i||destroyed[j].city2==i)
{
continue;
}
int index = unionset(cityset,destroyed[j].city1,destroyed[j].city2);
if(index>0){
cnt = cityset[index] < cnt ? cityset[index]:cnt;
cost += destroyed[j].weight;
}
}
if(cnt== -n+1&& cost && cost == max_cost)
{
pro.insert(i);
}
else if(cnt == -n+1 && cost && cost > max_cost)
{
pro.clear();
pro.insert(i);
max_cost = cost;
}
else if(cnt > -n + 1 && max_cost == MAX)
{
pro.insert(i);
}
else if(cnt > -n + 1 && max_cost != MAX)
{
pro.clear();
pro.insert(i);
max_cost = MAX;
}
}
if(pro.size()){
set<int>::iterator it = pro.begin();
printf("%d",*it++);
for(; it != pro.end();it++)
{
printf(" %d",*it);
}
}
else{
puts("0");
}
delete[] cityset;
delete[] use;
delete[] destroyed;
return 0;
}
int cmp(const void *v1, const void *v2)
{
road *r1, *r2;
r1 = (road *)v1;
r2 = (road *)v2;
return r1->weight - r2->weight;
}
int findroot(int cityset[], int index)
{
if(cityset[index] < 0)
{
return index;
}
else
{
return cityset[index] = findroot(cityset, cityset[index]);
}
}
int unionset(int cityset[], int index1, int index2)
{
int root1,root2;
root1 = findroot(cityset,index1);
root2 = findroot(cityset,index2);
if(root1 == root2)
{
return -1;
}
else
{
if(cityset[root1]>cityset[root2]){
cityset[root2] += cityset[root1];
cityset[root1] = root2;
return root2;
}
else
{
cityset[root1] += cityset[root2];
cityset[root2] = root1;
return root1;
}
}
}