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);
}
}