Problem - D - Codeforces
Chouti已经厌倦了乏味的作业,于是他打开了数年前创建的一个旧编程问题。
给定一个具有n个节点和m条加权边的连通无向图。其中有k个特殊节点:x1,x2,...,xk。
现在定义路径的成本为其边权的最大值。两个顶点之间的距离定义为连接它们的路径的最小成本。
对于每个特殊节点,请找到与其距离最远(根据上述定义,即相应距离是可能的最大值)的另一个特殊节点,并输出它们之间的距离。
由于原始限制非常小,所以他认为这个问题很无聊。现在,他提高了限制,并希望您能为他解决这个问题。
输入 第一行包含三个整数n、m和k(2≤k≤n≤105,n−1≤m≤105)——节点数、边数和特殊节点数。
第二行包含k个不同的整数x1,x2,…,xk(1≤xi≤n)。
接下来的m行,每行包含三个整数u、v和w(1≤u,v≤n,1≤w≤109),表示存在一条权值为w的边连接u和v。给定的图是无向的,因此边(u,v)可以在两个方向上使用。
图可能有多条边和自环。
保证图是连通的。
输出 第一行应包含k个整数。第i个整数是xi与离它最远的特殊节点之间的距离。
Examples
input
Copy
2 3 2 2 1 1 2 3 1 2 2 2 2 1
output
Copy
2 2
input
Copy
4 5 3 1 2 3 1 2 5 4 2 1 2 3 2 1 4 4 1 3 3
output
Copy
3 3 3
在第一个例子中,顶点 1 和顶点 2 之间的距离等于 2,因为它们之间有一条权重为 2 的边。因此,对于顶点 1 和顶点 2 来说,到最远节点的距离都是 2。
在第二个例子中,可以发现顶点 1 和顶点 2 之间、顶点 1 和顶点 3 之间的距离都是 3,而顶点 2 和顶点 3 之间的距离是 2。
该图可能存在多个边和自环,如第一个例子所示。
题解:
由于我们找的是特殊节点之间的最短距离,这道题比较特殊的是两点间的路径长度为,中间遍历过的最大边权值
由于题中两点距离是最小成本,相当于两点最小的路径长度,既然求的最小我们可以先利用最小生成树,把不需要的边去掉,这样一定最优
现在就变成了一棵树了,那么从任意一个特殊点开始,到其他所有特殊点,中途遍历过最长的边权,就是
离它最远的特殊节点之间的距离
这个距离对于所有特殊点,都适用文章来源:https://www.toymoban.com/news/detail-428476.html
因为我们是从一个特殊点开始的,我们找的这个最长边权的两侧,肯定都有特殊点,这样两边的点都可以经过这个最长边权文章来源地址https://www.toymoban.com/news/detail-428476.html
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
#define int long long
typedef pair<int,int> PII;
int mod = 998244353;
int n,m,k;
struct node
{
int l,r,x;
}a[100050];
int b[100050];
int f[100050];
int cmp(node a,node b)
{
return a.x < b .x;
}
int find(int x)
{
if(f[x] == x)
return x;
return f[x] = find(f[x]);
}
vector<PII> p[100050];
int d[100050];
void dfs(int x,int fa)
{
for(PII ne:p[x])
{
if(ne.first == fa)
continue;
d[ne.first] = max(d[x],ne.second);
dfs(ne.first,x);
}
}
void solve()
{
cin >> n >> m >> k;
for(int i = 1;i <= k;i++)
{
cin >> b[i];
}
for(int i = 1;i <= m;i++)
{
cin >> a[i].l >> a[i].r >> a[i].x;
}
for(int i = 1;i <= n;i++)
f[i] = i;
sort(a + 1,a + 1 + m,cmp);
for(int i = 1;i <= m;i++)
{
int x = find(a[i].l);
int y = find(a[i].r);
if(x != y)
{
f[x] = y;
p[a[i].l].push_back({a[i].r,a[i].x});
p[a[i].r].push_back({a[i].l,a[i].x});
}
}
dfs(b[1],0);
int ma = 0;
for(int i = 1;i <= k;i++)
ma = max(ma,d[b[i]]);
for(int i = 1;i <= k;i++)
cout << ma <<" ";
}
//5 7 8 9 10
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t = 1;
// cin >> t;
while(t--)
{
solve();
}
}
到了这里,关于D. Maximum Distance(最小生成树)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!