CSP201812_4 数据中心
我的思路:
这道题是看似内容很丰富,实则就是求最大权值最小的一棵生成树,然后,继续思考一下,最小生成树正好满足最大权值最小的条件,所以,这道题其实就是求最小生成树的问题。考虑清楚这一点,我们就可以利用Kruskal算法,每次选择最短边,然后利用并查集判断是否符合要求的方法,来解决这道题。
我的总结:
对于题干很复杂的问题,可能经过转换就是我们很熟悉的问题,所以对于一道题,先好好思考一下是很重要的。
我的代码:
#include<cstdio>
#include<algorithm>
using namespace std;
struct Edg
{
int A,B,len;
//Edg(int a,int b,int l) {A=a,B=b,len=l;}
bool operator < (const Edg x) const
{
return len<x.len;
}
};
struct Edg edg[10000001];
int par[100001],rnk[100001],n,a,m,rt,cot=0,ans=0;
bool is;
void init(){for(int i=1;i<=n;i++) par[i]=i,rnk[i]=1;}
int find(int x) {return par[x]==x?x:par[x]=find(par[x]);}
bool unit(int x,int y)
{
x=find(x),y=find(y);
if(x==y) return false;
if(rnk[x]>rnk[y]) swap(x,y);
par[x]=y,rnk[y]=(rnk[x]+=rnk[y]);
return true;
}
int main()
{
scanf("%d%d%d",&n,&m,&rt);
//printf("end1!\n");
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&edg[i].A,&edg[i].B,&edg[i].len);
}
//printf("end2!\n");
sort(edg,edg+m);
init();
for(int i=0;i<m;i++)
{
int x=edg[i].A,y=edg[i].B;
if(unit(x,y)) {
ans=edg[i].len>ans?edg[i].len:ans;
cot++;
//printf("%d\n",edg[i].len);
if(cot==n-1) break;
}
}
printf("%d",ans);
return 0;
}