hdu 4008 树形dp

来源:互联网 发布:怎么做网站优化 编辑:程序博客网 时间:2024/05/30 04:29


dfn[N][2],时间戳,标记dfs时访问改点的开始时间和结束时间。

根据时间戳,就能判断x点是否为y点的子孙。

然后考虑一下,dp[][],数组需要存什么东西。。

分情况讨论一下~

思路:http://fszxwfy.blog.163.com/blog/static/4401930820139804045831/


#include<stdio.h>  #include<string.h>  #include<math.h>  #include<stdlib.h>  #include<iostream>#include<algorithm>#include<queue>#include<vector>#include<set>#include<map>using namespace std;#define ll long longconst int inf = 0x3f3f3f3f;const ll int64 = (ll)inf * inf;#define N 100010int dfn[N][2],minson[N][2],mindes[N],fa[N];vector<int> f[N];int index;void dfs(int v,int fu){int i,j,len,u;len=f[v].size();fa[v]=fu;for(i=0;i<len;i++){u=f[v][i];if(u==fu){f[v].erase(f[v].begin()+i);i--;len--;continue;}dfn[u][0]=index++;dfs(u,v);dfn[u][1]=index++;mindes[v]=min(mindes[v],mindes[u]);mindes[v]=min(mindes[v],u);if(u<minson[v][1]){if(u<minson[v][0]){minson[v][1]=minson[v][0];minson[v][0]=u;}elseminson[v][1]=u;}}}int find(int x,int y){int l=0,r=f[y].size()-1,mid,u;while(1){mid=(l+r)/2;u=f[y][mid];if(dfn[u][0]<=dfn[x][0] && dfn[u][1]>=dfn[x][1])return u;else if(dfn[x][0]>dfn[u][1])l=mid+1;elser=mid-1;}}int main(){int t;scanf("%d",&t);while(t--){int n,q,i,j,k,a,b;memset(minson,inf,sizeof(minson));memset(mindes,inf,sizeof(mindes));scanf("%d%d",&n,&q);for(i=0;i<=n;i++)f[i].clear();for(i=1;i<n;i++){scanf("%d%d",&a,&b);f[a].push_back(b);f[b].push_back(a);}index=0;dfn[1][0]=index++;dfs(1,-1);dfn[1][1]=index++;int temp[2];temp[0]=temp[1]=inf;int len=f[1].size();int he=0;for(i=0;i<len;i++){b=f[1][i];a=min(b,mindes[b]);if(a<temp[1]){if(a<temp[0]){temp[1]=temp[0];temp[0]=a;he=b;}elsetemp[1]=a;}}int x,y;while(q--){scanf("%d%d",&x,&y);if(!(dfn[x][0]>dfn[y][0] && dfn[x][1]<dfn[y][1])){if(f[y].size()==0)printf("no answers!\n");elseprintf("%d %d\n",minson[y][0],mindes[y]);}else{int fx=find(x,y);if(y!=1){if(fx!=minson[y][0])printf("%d %d\n",min(fa[y],minson[y][0]),1);elseprintf("%d %d\n",min(fa[y],minson[y][1]),1);}else{if(fx!=minson[y][0])a=minson[y][0];elsea=minson[y][1];if(he!=fx)b=temp[0];elseb=temp[1];if(f[1].size()==1)printf("no answers!\n");elseprintf("%d %d\n",a,b);}}}printf("\n");}}


0 0