[SCOI2005]繁忙的都市
把交叉路口看做图中的点,道路为边,则可以从三个条件:
1.改造的那些道路能够把所有的交叉路口直接或间接的连通起来。
2.在满足要求1的情况下,改造的道路尽量少。
3.在满足要求1、2的情况下,改造的那些道路中分值最大的道路分值尽量小。
可得,本题是一个裸的最小生成树。
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; int n,m,u,v,c,ans=-1<<30,cnt; int fa[50005]; struct Node{ int u; int v; int c; }a[50005]; inline int Find(int x){ if(fa[x]!=x)fa[x]=Find(fa[x]); return fa[x]; } inline void Union(int x,int y){ int f1,f2; f1=Find(x),f2=Find(y); if(f1!=f2)fa[f1]=f2; return ; } inline bool cmp(const Node &a,const Node &b){ return a.c<b.c; } int main(){ scanf("%d%d",&n,&m); for(register int i=1;i<=m;i++) scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].c); for(register int i=1;i<=n;i++) fa[i]=i; sort(a+1,a+m+1,cmp); for(register int i=1;i<=m;i++){ if(Find(a[i].u)!=Find(a[i].v)){ Union(a[i].u,a[i].v); if(ans<a[i].c)ans=a[i].c; cnt++; } } printf("%d %d\n",cnt,ans); return 0; }