路线规划
nowcoder 217603
题目大意
给一个无向连通图,问你在经过的边最少的前提下,从1走过所有点,再走回1的最短距离
解题思路
对于求出来的路线中,设从1到最后一个点的路径为干线(如图下图,最后一个点为5,干线为1-2-3-5)
对于干线上的边(如2-3),来回各会走两遍
而对于非干线上的边,在去的时候,要离开干线,再回到干线,共两遍
而回来的时候不用走
所以无论是干线上的边还是非干线上的边,都会走两遍
那么对该图做最小生成树,使得所有点都到过一遍,然后乘2即可
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n, m, x, y, num, ans, fa[200021];
struct node
{
ll x, y, l;
}a[2000021];
bool cmp(node a, node b)
{
return a.l < b.l;
}
ll find(ll x)
{
return x == fa[x]?x:fa[x] = find(fa[x]);
}
int main()
{
scanf("%lld%lld", &n, &m);
for (ll i = 1; i <= m; ++i)
scanf("%lld%lld%lld", &a[i].x, &a[i].y, &a[i].l);
sort(a + 1, a + 1 + m, cmp);
for (ll i = 1; i <= n; ++i)
fa[i] = i;
num = 1;
for (ll i = 1; i <= m; ++i)//最小生成树
{
x = find(a[i].x);
y = find(a[i].y);
if (x != y)
{
num++;
ans += a[i].l;//记录边权
fa[x] = y;
if (num == n) break;//这里要用num记录一下,如果所有点都到过了,就直接退出,以减少时间,不然会T
}
}
printf("%lld", ans * 2);
return 0;
}

京公网安备 11010502036488号