【JZOJ2017.08.14C组T3】羊羊修路(最小生成树)
题目描述
经过特色示范羊村检查,检查组觉得羊村的道路需要重修,破败的道路,会影响到小羊们上学的安全。
村长组织施工队,开始丈量距离,规划施工方案,已经得到了若干建筑物间修建道路的可行方案,共有N个建筑物,和M条可选道路。这些路保证可以将N个建筑相连。
最终方案中,羊村打算修建全球最豪华的全大理石道路,道路可以双向通行,且一体成型,路中无缝隙。为了达到这个设计要求,就必须自建大理石工厂!
大理石工厂建造的难度在于,必须根据其需要生产最大长度的大理石来设计。工厂可以生产出不超过其设计极限的任意长度的大理石。例如,设计长度为100的工厂,可以生产100、90等长度的大理石,但是不能生产长度为101的大理石。
羊村的预算有限,希望你能帮忙规划出一个修路方案,使得工厂的设计规模尽可能小,且可以保证其能生产的大理石可以连通所有羊村的建筑。求出工厂的最小设计规模。
输入
第一行两个整数N和M,N表示羊村中的建筑数量,M表示可以修建的道路数量。
接下来M行,每行三个整数Ai,Bi和Ci,表示从建筑Ai,到建筑Bi,可以修建一条长度为Ci的道路。
注意,建筑编号从1到N,两个建筑之间可能有多条道路。
输出
输出大理石工厂的最小设计规模
赤裸裸的最小生成树,只是将路径总和改成最长路径而已。
1 #include <algorithm> 2 #include <cstdio> 3 4 struct edge{ 5 int from,to; 6 long long dist; 7 }e[10001]; 8 9 int n,m,pre[2001]; 10 long long ans; 11 #define max(x,y) x>y?x:y 12 13 bool cmp(edge x,edge y){ 14 return x.dist<y.dist; 15 } 16 17 int find(int x){ 18 while(x!=pre[x]) 19 x=pre[x]; 20 return x; 21 } 22 23 void join(int x,int y){ 24 int fx=find(x); 25 int fy=find(y); 26 if(fx!=fy)pre[fx]=fy; 27 } 28 29 int main(void){ 30 scanf("%d%d",&n,&m); 31 for(int i=1;i<=n;++i) 32 pre[i]=i; 33 for(int i=1;i<=m;++i) 34 scanf("%d%d%lld",&e[i].from,&e[i].to,&e[i].dist); 35 std::sort(e+1,e+m+1,cmp); 36 for(int i=1;i<=m;++i){ 37 if(find(e[i].from)!=find(e[i].to)){ 38 ans=max(ans,e[i].dist); 39 join(e[i].from,e[i].to); 40 } 41 } 42 printf("%lld",ans); 43 }