标签:
我以0为根节点建树,然后做树形dp,first和second就不用说了吧,先两遍dfs找树的直径,在找fir+sec==树的直径(table)的点进行搜索,最后扫一遍所有的点出答案。
虽然慢了点,但能A就行。
1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 bool p[200003]; 7 int point[200003],next[400003],v[400003],cnt=0,N,kk,dist[200003],first[200003],second[200003]; 8 void insect(int u,int vv){next[cnt]=point[u];point[u]=cnt;v[cnt]=vv;cnt++;} 9 void bfs(int k) 10 { 11 queue<int>q; memset(dist,0,sizeof(dist)); 12 q.push(k); dist[k]=1; int now,i; 13 while (!q.empty()) 14 { 15 now=q.front(); q.pop(); 16 for (i=point[now];i!=-1;i=next[i]) 17 if (dist[v[i]]==0){dist[v[i]]=dist[now]+1;q.push(v[i]);if (dist[v[i]]>dist[kk]) kk=v[i];} 18 } 19 } 20 void dp(int x) 21 { 22 int i=0; p[x]=1; 23 for (i=point[x];i!=-1;i=next[i]) 24 { 25 if (p[v[i]]==0) 26 { 27 dp(v[i]); 28 if (first[x]<=first[v[i]]+1) {second[x]=first[x];first[x]=first[v[i]]+1;} 29 else if (second[x]<=first[v[i]]+1) second[x]=first[v[i]]+1; 30 } 31 }if (first[x]==0) first[x]=1; 32 } 33 void work2(int x) 34 { 35 int i; p[x]=1; 36 for (i=point[x];i!=-1;i=next[i]) 37 if ((p[v[i]]==0)&&(first[v[i]]==first[x]-1)) 38 work2(v[i]); 39 } 40 void work(int x,int fir,int sec) 41 { 42 int i; p[x]=1; 43 for (i=point[x];i!=-1;i=next[i]) 44 if (((first[v[i]]==fir-1)||(first[v[i]]==sec-1))) work2(v[i]); 45 } 46 int main() 47 { 48 memset(next,-1,sizeof(next)); 49 memset(v,0,sizeof(v)); 50 memset(point,-1,sizeof(point)); 51 scanf("%d\n",&N); 52 int i,x,y,begin,table; 53 for (i=1;i<N;++i){scanf("%d %d\n",&x,&y);insect(x,y);insect(y,x);} 54 bfs(0); begin=kk; bfs(begin); table=dist[kk]; memset(p,0,sizeof(p)); 55 dp(0); memset(p,0,sizeof(p)); 56 for (i=0;i<=N;++i) if (first[i]+second[i]==table+1) work(i,first[i],second[i]); 57 for (i=0;i<=N;++i) if (p[i]) printf("%d\n",i); 58 return 0; 59 }
Vijos P1476 旅游规划(csapc) 聪哥说我根本不理解树形DP23333333333
标签:
原文地址:http://www.cnblogs.com/abclzr/p/5089435.html