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