大体题意:
一个老鼠从A点出发,经过一个环回到起点,他可能走到任意地点, 让你在一些边上放摄像头,使得无论老鼠怎么走,总有一个摄像头能看到老鼠!
摄像头的成本是这条边的权值!
思路:
既然他可以走到任意点,所以每个点都要能监视到,而且权值最小,而且有环,先求一个最大生成树!因为有环,旁边的点一定可以监视到这个最大生成树,这样保证了,可以监视整个图,也保证了权值和不是最大,剩下的在非最大生成树中找到一个最大点作为第二个输出即可!
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100000 + 10;
struct Edge{
int x,y,w;
bool operator < (const Edge& rhs) const {
return w > rhs.w;
}
}p[maxn];
int fa[maxn],vis[maxn];
int find(int x){
return x == fa[x] ? fa[x] : fa[x] = find(fa[x]);
}
int main(){
int T,kase = 0;
scanf("%d",&T);
while(T--){
memset(vis,0,sizeof vis);
int u, v, w;
int n, m;
scanf("%d %d",&n,&m);
for (int i = 0; i < m; ++i){
scanf("%d %d %d",&u,&v,&w);
p[i].x = u;
p[i].y = v;
p[i].w = w;
}
sort(p,p+m);
for (int i = 0; i <= n; ++i)fa[i] = i;
int cnt = n;
for (int i = 0; i < m; ++i){
int xx = find(p[i].x);
int yy = find(p[i].y);
if (xx != yy){
vis[i] = 1;
fa[yy] = xx;
--cnt;
}
if (cnt == 1)break;
}
int Max = -1;
int sum = 0;
for (int i = 0; i < m; ++i){
if (vis[i])continue;
Max = max(Max,p[i].w);
sum += p[i].w;
}
printf("Case #%d: %d %d\n",++kase,sum,Max);
}
return 0;
}