A. Wormhole Sort
https://codeforces.com/group/5yyKg9gx7m/contest/270203/problem/A
分析:
首先可以想到二分w。判断其中一个数x是否符合要求,考虑并查集。把大于x的w放在一个集合。看这个集合中,所有错位母牛的编号和他的位置是不是在这个集合中。如果在这个集合中表示互相可达。只考虑错位母牛的话,只要他的编号和位置都在一个集合,就表示可以互相换,这样始终可以让他归位。(类似冒泡)
代码:
#include <cstdio> #include <algorithm> #include <iostream> using namespace std; typedef long long ll; const int maxn=1e5+6; struct cop { int u,v; int w; }c[maxn]; int p[maxn]; int a[maxn]; int fa[maxn]; int n,m; int dis; int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } void Union(int x,int y) { x=find(x),y=find(y); fa[x]=y; } bool same(int x,int y) { return find(x)==find(y); } bool judge(int x) { for(int i=1;i<=n;i++) fa[i]=i;//初始化 for(int i=x;i<=m;i++) { Union(c[i].u,c[i].v); } for(int i=1;i<=dis;i++) { if(!same(a[p[i]],p[i])) return 0; } return 1; } bool cmp(struct cop a,struct cop b) { return a.w<b.w; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(a[i]!=i) p[++dis]=i; } for(int i=1;i<=m;i++) { scanf("%d %d %d",&c[i].u,&c[i].v,&c[i].w); } if(!dis) { printf("-1\n"); return 0; } sort(c+1,c+m+1,cmp); int l=1,r=m; int mid=(l+r)>>1; while(l<=r) { mid=(l+r)>>1; if(judge(mid)) l=mid+1; else r=mid-1; } cout<<c[l-1].w<<endl; return 0; }