BZOJ 1509[NOI 2003]逃学的小孩 树形dp
1509: [NOI2003]逃学的小孩
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 995 Solved: 505
[Submit][Status][Discuss]
Description
Input
第一行是两个整数N(3 N 200000)和M,分别表示居住点总数和街道总数。以下M行,每行给出一条街道的信息。第i+1行包含整数Ui、Vi、Ti(1Ui, Vi N,1 Ti 1000000000),表示街道i连接居住点Ui和Vi,并且经过街道i需花费Ti分钟。街道信息不会重复给出。
Output
仅包含整数T,即最坏情况下Chris的父母需要花费T分钟才能找到Chris。
Sample Input
4 3
1 2 1
2 3 1
3 4 1
1 2 1
2 3 1
3 4 1
Sample Output
4
题解:
这道题目只能讲这个很关键,所以记录第二长的边乘以两倍,就OK了
什么树形dp,没有的。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #include<iostream> 5 #include<cstring> 6 #define N 200007 7 #define ll long long 8 using namespace std; 9 10 int n,m;ll ans; 11 int cnt,head[N],next[N*2],rea[N*2];ll val[N*2]; 12 bool boo[N]; 13 struct Node 14 { 15 int pos;ll dis; 16 }a[N][4]; 17 18 bool cmp(Node x,Node y){return x.dis>y.dis;} 19 void add(int u,int v,int fee){next[++cnt]=head[u],head[u]=cnt,rea[cnt]=v,val[cnt]=fee;} 20 void dfs_init(int u,int fa) 21 { 22 for (int i=head[u];i!=-1;i=next[i]) 23 { 24 int v=rea[i],fee=val[i]; 25 if (v==fa) continue; 26 dfs_init(v,u); 27 a[u][3].pos=v; 28 a[u][3].dis=a[v][0].dis+fee; 29 sort(a[u]+0,a[u]+3+1,cmp); 30 } 31 ans=max(ans,a[u][0].dis+2*a[u][1].dis+a[u][2].dis); 32 } 33 void dfs_solve(int u) 34 { 35 boo[u]=1; 36 for (int i=head[u];i!=-1;i=next[i]) 37 { 38 int v=rea[i],fee=val[i]; 39 if (boo[v]) 40 { 41 if (a[v][0].pos!=u) a[u][3].dis=a[v][0].dis+fee; 42 else a[u][3].dis=a[v][1].dis+fee; 43 a[u][3].pos=v; 44 sort(a[u]+0,a[u]+3+1,cmp); 45 break; 46 } 47 } 48 ans=max(ans,a[u][0].dis+2*a[u][1].dis+a[u][2].dis); 49 for (int i=head[u];i!=-1;i=next[i]) 50 { 51 int v=rea[i]; 52 if (!boo[v]) dfs_solve(v); 53 } 54 } 55 int main() 56 { 57 memset(head,-1,sizeof(head)); 58 scanf("%d%d",&n,&m); 59 int x,y,z; 60 for (int i=1;i<=m;i++) 61 { 62 scanf("%d%d%d",&x,&y,&z); 63 add(x,y,z),add(y,x,z); 64 } 65 dfs_init(1,-1); 66 dfs_solve(1); 67 printf("%lld\n",ans); 68 }