2418. Wormhole Sort

2418. Wormhole Sort

(File IO): input: wormsort.in output: wormsort.out
Time limit: 1000 ms Space limit: 262144 KB Specific limit
Goto ProblemSet


Title description

Farmer John ’s cows were tired of his request to leave the barn in order every morning. They have just completed a Ph.D. in quantum physics and are ready to make this process faster.
This morning, as usual, Farmer John ’s N cows numbered 1 ... N (1≤N≤10 ^ 5) were scattered in N different positions numbered 1 ... N in the cowshed, and cow i was at position pi . But this morning there were also M wormholes numbered 1 ... M (1≤M≤10 ^ 5), where the wormhole i connected the positions ai and bi in both directions, and the width was wi (1≤ai, bi≤N, ai ≠ bi, 1≤wi≤10 ^ 9).
At any time, two cows located at both ends of a wormhole can choose to exchange positions through the wormhole. The cows need to repeat this exchange until the cow i is at position i for 1 ≤ i ≤ N.
The cows don't want to be crushed by the wormhole. Help them maximize the minimum width of the wormhole they use to sort. Make sure that the cows are in order.

Input

The first line of input contains two integers N and M.
The second line contains N integers p1, p2, ..., pN. Ensure that p is a permutation of 1 ... N.
For each i between 1 and M, line i + 2 contains the integers ai, bi, and wi.

Output

An integer is output, which is the maximum value of the minimum width of the wormhole that the cow must squeeze into during the sorting process. If the cows do not need to use any wormhole to sort, output −1.

Sample input

4 4
3 2 1 4
1 2 9
1 3 7
2 3 10
2 4 3

Sample output

9

Data range limitation

Test points 1-5 satisfy N, M≤1000.
Test points 6-10 have no additional restrictions.

Hint: The
following is a possible solution for sorting cows using only wormholes with a width of at least 9:

Cow 1 and Cow 2 use the third wormhole to swap places.
Cow 1 and Cow 3 use the first wormhole to swap places.
Cow 2 and Cow 3 use the third wormhole to swap places.

The main data structure: the difference set. The main
idea: let the ith cow return to the p [i] cattle farm.

 用并查集就是判断一下第i头牛和第p[i]个牛场是否在同一个
 集合(集合内所有的牛都可进行交换),如果他们的祖先相同,
 那么便能归位。

method one

For the input data, first arrange them in descending order according to the width of the wormhole (once the conditions are met, it must be the optimal solution), and finally only need to simulate the exchange process.
But you can't go to judge whether the cow is in place every time, because it will time out.
After careful scrutiny, we can know a property:

If the current point has been homed, it will not be affected in future exchanges.
After understanding this, we only need to count the number of cattle that are homing.
Time complexity: O (m + n);

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e5+10;
struct node
{
	int u,v,w;
} cow[N];
int n,m,p[N],f[N];
bool ff;
void input()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) 
	{
		scanf("%d",&p[i]);   
		if(p[i]!=i) ff=1;  
		f[i]=i;	
	}
	for(int i=1;i<=m;i++) scanf("%d%d%d",&cow[i].u,&cow[i].v,&cow[i].w);
}
bool cmp(node x,node y) {return x.w>y.w;}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
int main()
{
	//fre(wormsort);
	input();
	if(!ff) //特判一开始全都在原位 
	{
		printf("-1");  
		return 0;	
	}
	sort(cow+1,cow+1+m,cmp);
	int j=1;
	for(int i=1;i<=m;i++)
	{
		int a=find(cow[i].u),b=find(cow[i].v);
		if(a!=b) f[a]=f[b]; 
		while(find(p[j])==find(j)) j++;  
		//当一个点已经满足要求时,那么在加边还是满足要求
		//j巧用数组下标,因为没有第0头牛
		if(j>n) 
		{
			printf("%d\n",cow[i].w);
			return 0;
		}
	}
	return 0;
}

Method Two

In fact, the idea is the same as above, but we don't need to enumerate the wormholes one by one as the minimum distance.
The data satisfies the order, so you can consider using dichotomy (minimum distance).
But be careful: if you are sorting in descending order, then your l should be equal to the last value, and r equal to the first value, because l <= r.
Time complexity: O (nlogn);

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e5+10;
struct node
{
	int u,v,w;
} cow[N];
int n,m,p[N],f[N],l,r;
bool ff;
void input()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) 
	{
		scanf("%d",&p[i]);   
		if(p[i]!=i) ff=1;  
	}
	for(int i=1;i<=m;i++) scanf("%d%d%d",&cow[i].u,&cow[i].v,&cow[i].w);
}
bool cmp(node x,node y) {return x.w>y.w;}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
bool check(int minl)
{
	int j=1;
	for(int i=1;i<=n;i++) f[i]=i;	
	for(int i=1;i<=m&&cow[i].w>=minl;i++)
	{
		int a=find(cow[i].u),b=find(cow[i].v);
		f[a]=b;
	}
	for(int i=1;i<=n;i++) if(find(i)!=find(p[i])) return 0;
	return 1;
}
int main()
{
	//fre(wormsort);
	input();
	if(!ff) //特判一开始全都在原位 
	{
		printf("-1");  
		return 0;	
	}
	sort(cow+1,cow+1+m,cmp);
	int l=cow[m].w,r=cow[1].w,mid,ans;
	while(l<=r)
	{
		mid=(l + r) >> 1;
		if(check(mid)) l = mid+1,ans=mid;
		else r = mid-1;
	}
	printf("%d",ans);
	return 0;
}

Published 130 original articles · Like 93 · Visitors 6796

Guess you like

Origin blog.csdn.net/bigwinner888/article/details/105496859