本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P2330
这是一道省选题。。。但却是普及组的难度,是我们变强了吗?
这道题其实是对最小生成树基本性质的考察,首先,对于一个有n个点的图,要想连通所有点,最少需要n-1条边(刚好连通且没有环,其实就是树)。再者,对于一个有n个点,m条边的图,他的最小生成树一定是所有生成树当中,最大边权最小的(显然,可以想象一下Kruskal的过程)。那这道题就没什么好说的了,彻彻底底一道水题。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=305,maxm=5e4+5; 5 int n,m,cnt,fa[maxn]; 6 struct edge { 7 int u,v,c; 8 bool operator < (const edge& rhs) const { 9 return c<rhs.c; 10 } 11 } E[maxm]; 12 int f(int i) { 13 if(fa[i]==i) return i; 14 return fa[i]=f(fa[i]); 15 } 16 void dj_merge(int a,int b) { 17 a=f(a);b=f(b); 18 if(a!=b) fa[a]=b; 19 } 20 int main() { 21 scanf("%d%d",&n,&m); 22 for(int i=1;i<=m;++i) scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].c); 23 sort(E+1,E+m+1); 24 for(int i=1;i<=n;++i) fa[i]=i; 25 for(int i=1;i<=m;++i) 26 if(f(E[i].u)!=f(E[i].v)) { 27 dj_merge(E[i].u,E[i].v); 28 ++cnt; 29 if(cnt==n-1) { 30 printf("%d %d",n-1,E[i].c); 31 return 0; 32 } 33 } 34 return 0; 35 }