杭电OJ4607-Park Visit
题意:对于一棵给定的最小生成树,遍历其中固定的顶点数所需要的最短距离
分析:利用树形DP或者两次BFS求出树的直径即可得解
input:
2
13 4
1 2
2 3
2 4
5 4
4 6
6 8
6 9
7 8
9 10
8 11
11 12
11 13
5
7
9
13
output:
4
6
10
18
//Time 842ms //Memory 5940k //Date 2015.03.30 #include <iostream> #include <algorithm> #include <cstring> #include <vector> //#include <cstdio> using namespace std; const int MAXN=100001; int n,m,d; vector<int> Edge[MAXN]; int dis[MAXN]; void Tree_Diam(int r,int f){ //树形DP int v; vector<int>::iterator it; dis[r]=1; for(it=Edge[r].begin();it!=Edge[r].end();it++){ v=*it; if(v!=f){ //排除父节点 Tree_Diam(v,r); d=max(d,dis[r]+dis[v]); dis[r]=max(dis[r],dis[v]+1); } } } int main(){ // freopen("in.txt","r",stdin);//调试 int t,i,j,k,u,v; scanf("%d",&t); for(i=0;i<t;i++){ scanf("%d%d",&n,&m); for(j=1;j<=n;j++) Edge[j].clear(); for(j=1;j<n;j++){ scanf("%d%d",&u,&v); Edge[u].push_back(v); Edge[v].push_back(u); } d=0; memset(dis,0,sizeof(dis)); Tree_Diam(1,0); for(j=0;j<m;j++){ scanf("%d",&k); if(k<=d) printf("%d\n",k-1); else printf("%d\n",d-1+(k-d)*2); } } // fclose(stdin); return 0; }
//Time 1060ms //Memory 9096k //Date 2015.03.30 #include <iostream> #include <cstring> #include <vector> #include <queue> using namespace std; class Node{ public: int id; int level[2]; Node(int i,int l1=0,int l2=0){ id=i;level[0]=l1;level[1]=l2; } }; const int MAXN=100001; int n,m; vector<Node> Edge[MAXN]; int visit[MAXN]; Node BFS(Node u0,int flag){ Node u(0),v(0),result(0); vector<Node>::iterator it; queue<Node> q; visit[u0.id]=flag; q.push(u0); while(!q.empty()){ u=q.front();q.pop(); for(it=Edge[u.id].begin();it!=Edge[u.id].end();it++){ v=*it; if(visit[v.id]!=flag){ visit[v.id]=flag; v.level[flag]=u.level[flag]+1; result=v; q.push(v); } } } return result; } int Tree_Diam(int r){ //两次BFS memset(visit,-1,sizeof(visit)); Node u(r,0,0); Node v1=BFS(u,0); Node v2=BFS(v1,1); return v2.level[1]; } int main(){ int t,i,j,k,u,v,d; scanf("%d",&t); for(i=0;i<t;i++){ scanf("%d%d",&n,&m); for(j=1;j<=n;j++) Edge[j].clear(); for(j=1;j<n;j++){ scanf("%d%d",&u,&v); Edge[u].push_back(Node(v)); Edge[v].push_back(Node(u)); } d=Tree_Diam(1); for(j=0;j<m;j++){ scanf("%d",&k); k--; if(k<=d) printf("%d\n",k); else printf("%d\n",d+(k-d)*2); } } return 0; }