每日一练~Shortest Path~解题报告

Shortest Path

文章目录

    • Shortest Path
    • 题目描述:
    • Input:
    • Output:
    • Sample Input:
    • Sample Output:
    • Hint:
    • 题目大意:
    • 思路分析:
    • 代码:

题目描述:

Today HH becomes a designer, and he faces a problem so he asks you for help.
Treeisland is a country with n cities and n−1 two-way road and from any city you can go to any other cities.
HH the designer is going to design a plan to divide n city into n/2 pairs so that the sum of the length between the n/2 pairs city is minimum.
Now HH has finished it but he doesn’t know whether it’s true so he ask you to calculate it together.
It’s guaranteed that n is even.

Input:

The first line contains an positive integer T(1≤T≤100), represents there are T test cases.
For each test case: The first line contains an positive integer n(1≤n≤104), represents the number of cities in Treeisland, it’s guarantee that n is even.
Then n−1 lines followed. Each line contains three positive integer u, v and len, (u≠v,1≤u≤n,1≤v≤n,1≤len≤109)indicating there is a road of length len between u and v.
It’s guarantee you can get to any city from any city.

Output:

For each test case, output in one line an integer, represent the minimum sum of length.

Sample Input:

2
4
1 2 5
2 3 8
3 4 6
6
1 3 5
3 2 3
4 5 4
4 3 9
4 6 10

Sample Output:

11
31

Hint:

每日一练~Shortest Path~解题报告_第1张图片

题目大意:

有一个地方有n个城市,每个城市之间有一个距离值,求出n/2对的城市之间最短距离之和。

思路分析:

这道题一开始的时候错误认为是直接从把每一个节点当作父子点,然后去搜索每一个节点,从子节点最短距离来判断,当找到最短就标记,然后就直接TL了,数据太大了。应该这样去看,用前向星链式去做各个点的边,题目给的是双向带权值图,所以做边的时候,要做双向。寻找最短距离一般都是在父节点和兄弟节点去寻找,然后当一个节点存在不是偶数边的时候,说明这个点需要与其他节点配对。

代码:

#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=3e5+6;
typedef struct node
{
	int to;
	int u;
	ll w;
}Lemon;
Lemon Frist[maxn];
ll head[maxn];
long long size[maxn];
ll cnt;
ll ans;
ll read()
{
	long long x=0;
	long long f=1;
	char c1=getchar();
	while(c1<'0' || c1>'9')
	{
		if(c1=='-')
		{
			f=-1;
		}
		c1=getchar();
	}
	while(c1>='0' && c1<='9')
	{
		x=x*10+c1-'0';
		c1=getchar();
	}
	return x*f;
}
void LemonADD(int u,int v,int z)
{
	Frist[cnt].u=head[u];
	Frist[cnt].to=v;
	Frist[cnt].w=z;
	head[u]=cnt++;
}
void LemonDFS(int u,int v,int z)
{
	size[u]=1;
	for(int i=head[u];i;i=Frist[i].u)
	{
		int h=Frist[i].to;
		if(h==v)continue;
		LemonDFS(Frist[i].to,u,Frist[i].w);
		size[u]+=size[h];
	}
	if(size[u]&1)ans+=z;
}
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		cnt=1;
		ans=0;
		memset(head,0,sizeof(head));
		long long n=read();
		ll z;
		int x,y;
		for(ll i=0;i<n-1;i++)
		{
			cin >> x >> y >> z;
			LemonADD(x,y,z);
			LemonADD(y,x,z);
		}
		LemonDFS(1,0,0);
		printf("%lld\n",ans);
	}
}

你可能感兴趣的:(每日一练~Shortest Path~解题报告)