来源 codeforces 2020 GDUT Rating Contest III (Div. 2) CF链接
题目:
Farmer John’s cows have grown tired of his daily request that they sort themselves before leaving the barn each morning. They have just completed their PhDs in quantum physics, and are ready to speed things up a bit.
This morning, as usual, Farmer John’s N cows (1≤N≤105), conveniently numbered 1…N, are scattered throughout the barn at N distinct locations, also numbered 1…N, such that cow i is at location pi. But this morning there are also M wormholes (1≤M≤105), numbered 1…M, where wormhole i bidirectionally connects location ai with location bi, and has a width wi (1≤ai,bi≤N,ai≠bi,1≤wi≤109).
At any point in time, two cows located at opposite ends of a wormhole may choose to simultaneously swap places through the wormhole. The cows must perform such swaps until cow i is at location i for 1≤i≤N.
The cows are not eager to get squished by the wormholes. Help them maximize the width of the least wide wormhole which they must use to sort themselves. It is guaranteed that it is possible for the cows to sort themselves.
Input
The first line contains two integers, N and M.
The second line contains the N integers p1,p2,…,pN. It is guaranteed 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
A single integer: the maximum minimal wormhole width which a cow must squish itself into during the sorting process. If the cows do not need any wormholes to sort themselves, output −1.
Examples
inputCopy
4 4
3 2 1 4
1 2 9
1 3 7
2 3 10
2 4 3
outputCopy
9
inputCopy
4 1
1 2 3 4
4 2 13
outputCopy
-1
Note
The first example is one possible way to sort the cows using only wormholes of width at least 9:
Cow 1 and cow 2 swap positions using the third wormhole. Cow 1 and cow 3 swap positions using the first wormhole. Cow 2 and cow 3 swap positions using the third wormhole.
The second example is no wormholes are needed to sort the cows.
题意:给定数条路径,要求每头牛经过某些路径回到自己编号的结点。使经过的最长边最短。
思路:不要局限在一维的数轴来思考,每个虫洞可以当做条连接i和j的双向路,于是这题就变成了图论题,用kruskal做最小生成树即可。每次选边之前判断牛是否已经归位。最后一条加进去的边长就是答案。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define INF 0x3f3f3f3f
#define mod 1000000007
#define pi acos(-1)
using namespace std;
int n,m,p[100050],t,pre[100050],ans=-1;
struct node
{
int u,v,d;
}edge[100050];
int find(int x)
{
if (pre[x]==x)
return x;
else pre[x]=find(pre[x]);
return pre[x];
}
void addedge(int u,int v,int w)
{
edge[++t].u=u;
edge[t].v=v;
edge[t].d=w;
}
void join(int x,int y)
{
if (find(x)!=find(y))
pre[find(y)]=find(x);
}
int cmp(node a,node b)
{
return a.d>b.d;
}
int main()
{
cin>>n>>m;
for (int i=1;i<=n;i++)
cin>>p[i];
for (int i=1;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
addedge(u,v,w);
}
sort(edge+1,edge+t+1,cmp);
for (int i=1;i<=n;i++) pre[i]=i;
int k=0,j;
for (int i=1;i<=t;i++)
{
for (j=1;j<=n;j++)
{
if (find(j)==find(p[j]))
continue;
else break;
}
if (j==n+1) break;
if (k==n-1) break;
if (find(p[edge[i].u])!=find(p[edge[i].v]))
{
join(p[edge[i].u],p[edge[i].v]);
k++;
ans=edge[i].d;
}
}
cout<<ans<<endl;
return 0;
}
探讨了在特定条件下,如何利用虫洞进行牛牛排序并最大化最小虫洞宽度的问题。通过将问题转化为图论中的最小生成树问题,使用Kruskal算法求解。
261

被折叠的 条评论
为什么被折叠?



