openjudge F:Delta Quadrant(坑)

来源:互联网 发布:埃尔金贝勒数据 编辑:程序博客网 时间:2024/06/05 16:16

总时间限制: 
3000ms 
内存限制: 
131072kB
描述

Much of the Delta Quadrant remains unexplored, but it is known that there are many dangerous regions inhabited by warring races. Yet, there is a small number of declared neutral zones that reach from planet to planet in which it is safe to travel.

A critical summit is planned, but it is on hold until a quorum of its members is attained. To reach this quorum, almost all of the delegates from the Delta Quadrant must be fetched and brought to the same location, where the Enterprise can pick them up for the summit.

The Enterprise is on its way to the Delta Quadrant. You must find the fastest way, using a single ship leaving from any one of the planets in the Delta Quadrant and returning to that same planet, to visit all but a given number of planets.

There are planets and N - 1 safe paths through neutral zones connecting the planets. Each path has a known time duration required for traversal. Find the shortest time required, starting from an arbitrary planet, to visit N - planets, and return.


输入
The first line contains T, the number of problems; 1 <= T <= 50. Each problem instance starts with a line with two integers, N, the number of planets, and k, the count of planets that need not be visited; 2 <= N <= 10,000 and 0 <= k <= min(N - 1,20). Following that are N-1 lines, each containing three integers, which are, in order, the source and destination planet numbers (from 0 to N - 1) and then the time required to traverse that path. The time is between 0 and 1, 000, 000, inclusive. The input graph will be connected.
输出
For each problem instance, print a single integer representing the final distance of travel required.
样例输入
32 00 1 30004 10 1 811 2 412 3 599 20 1 10001 2 12000 3 10003 4 12000 5 10005 6 12000 7 18007 8 600
样例输出
600020013200





【分析】

树形DP,未AC待填坑...真的已经蠢到不会写树DP了唉

为什么我写的DP都有后效性2333333333




【代码】

//openjudge pkusc2017 Round1.F#include<iostream>#include<cstring>#include<cstdio>#include<cmath> #define inf 1e18#define ll long long#define fo(i,j,k) for(i=j;i<=k;i++)using namespace std;const int mxn=10005;int n,m,T,cnt;ll dp[mxn][21],len[mxn],ans;int head[mxn],size[mxn],tmp[mxn],one[mxn];struct edge {int to,dis,next;} f[mxn<<1];inline void add(int u,int v,int d){f[++cnt].to=v,f[cnt].dis=d,f[cnt].next=head[u],head[u]=cnt;}inline void dfs(int u,int fa){size[u]=1;int num=0;for(int i=head[u];i;i=f[i].next){int v=f[i].to;if(v==fa) continue;dfs(v,u);size[u]+=size[v];}dp[u][0]=dp[u][size[u]]=dp[u][size[u]-1]=0;for(int i=head[u];i;i=f[i].next)  if(f[i].to!=fa) tmp[++num]=f[i].to,one[num]=f[i].dis;len[num+1]=0;for(int i=num;i;i--){int v=tmp[i];len[i]=len[i+1]+dp[v][0]+one[i];}num=0;for(int i=head[u];i;i=f[i].next){int v=f[i].to;if(v==fa) continue;num++;for(int j=min(m,size[u]-2);j>=0;j--)  for(int k=0;k<=min(j,size[v]);k++)    if(num==1 && j==0)      dp[u][j]=dp[v][k]+(ll)f[i].dis;    else if(k!=size[v])      dp[u][j]=min(dp[u][j],dp[v][k]+dp[u][j-k]+(ll)f[i].dis+len[num+1]);    else      dp[u][j]=min(dp[u][j],dp[v][k]+dp[u][j-k]+len[num+1]);}}int main(){int i,j,u,v,d;scanf("%d",&T);while(T--){cnt=0,ans=inf;memset(dp,0x3f,sizeof dp);memset(head,0,sizeof head);memset(size,0,sizeof size);scanf("%d%d",&n,&m);fo(i,2,n){scanf("%d%d%d",&u,&v,&d);add(u+1,v+1,d+d),add(v+1,u+1,d+d);}dfs(1,0);fo(i,1,n) if(m>=n-size[i])  ans=min(ans,dp[i][m-(n-size[i])]);printf("%lld\n",ans);}return 0;}/*19 20 1 10001 2 12000 3 10003 4 12000 5 10005 6 12000 7 18007 8 600*/



原创粉丝点击