每日一練~Shortest Path~解題報告

Shortest Path

題目描述:

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:

在這裏插入圖片描述

題目大意:

有一個地方有n個城市,每個城市之間有一個距離值,求出n/2對的城市之間最短距離之和。

思路分析:

這道題一開始的時候錯誤認爲是直接從把每一個節點當作父子點,然後去搜索每一個節點,從子節點最短距離來判斷,當找到最短就標記,然後就直接TL了,數據太大了。應該這樣去看,用前向星鏈式去做各個點的邊,題目給的是雙向帶權值圖,所以做邊的時候,要做雙向。尋找最短距離一般都是在父節點和兄弟節點去尋找,然後當一個節點存在不是偶數邊的時候,說明這個點需要與其他節點配對。

代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
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);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章