A. Wormhole Sort
题目描述
(还是看洛谷的中文题面吧)
题目分析
#参考了博客
(参考了博客后发现)原题可看作 位置不对的牛 想通过虫洞走到正确的位置,而且希望虫洞的宽度尽可能大(路的长度尽可能长),有kruskal内味了,而套用kruskal也就解决了。
貌似还有二分的做法,以后补上。。。
代码
#include <bits/stdc++.h>
using namespace std;
struct edge{
int from;
int to;
int dis;
}edg[100001];
bool cmp(edge a,edge b){
return a.dis>b.dis;
}
int root[100001];
void union_init(int n){
for(int i=1;i<=n;i++)
root[i]=i;
}
int union_search(int x){
while(x!=root[x])
x=root[x]=root[root[x]];//从dl处学来的
return x;
}
int n,m,cow[100001];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",cow+i);
for(int i=0;i<m;i++)
scanf("%d%d%d",&edg[i].from,&edg[i].to,&edg[i].dis);
sort(edg,edg+m,cmp);
union_init(n);
int ans=-1,rec_cow=1;
//kruskal
for(int i=0;i<m;i++){
while(root[rec_cow]==root[cow[rec_cow]]){
rec_cow++;
if(rec_cow>n){
printf("%d\n",ans);
return 0;
}
}
//说实话这里往下有点迷
int temp_a=union_search(cow[edg[i].from]),temp_b=union_search(cow[edg[i].to]);
if(temp_a!=temp_b){
root[temp_b]=temp_a;
ans=edg[i].dis;
}
}
printf("%d\n",ans);
}