前言:本来想写在一个博文里的。
但是太麻烦了。并且dp还没怎么看懂。
还是要努力啊。
再写一下dfs求树的直径就完事了。;
方法:我感觉spfa在这里面和bfs几乎差不多,唯一的差别就是松弛除了赋初值就没啥用了。
hdu4607
#include <iostream>
#include <bits/stdc++.h>
/*这道题写废了我也很痛心啊,
怎么spfa又忘记了啊。
今天晚上targin肯定可以搞定。
这几天再把三个targin写写,数位dp和压缩那个玩意
就写写模拟.准备省赛吧亲
本体方法和bfs十分像。先求一个最远的。然后再根据那个最远的。在求一个最远的。
我剪短的证明一下。
不过这个spfa和bfs也太tm像了。松弛也没用。树形结构松弛个毛。
*/
using namespace std;
const int maxn=100008;
struct Node
{ int to,cost;
Node(int a,int b){to=a;cost=b;};
Node(){};
};
Node node[maxn];
int dis[maxn];
vector <Node> G[maxn];
void add(int a,int b,int c)
{ G[a].push_back(Node(b,c));
//cout<<G[a].size()<<"尼玛?"<<endl;
G[b].push_back(Node(a,c));
//cout<<G[b].size()<<"kao"<<endl;
}
int spfa(int s)
{ queue<int>q;
bool vis[maxn];
memset(dis,0x3f,sizeof(dis));
memset(vis,false,sizeof(vis));
dis[s]=0;
q.push(s);
while(!q.empty())
{ int u=q.front();
//cout<<u<<"***"<<G[u].size()<<endl;
q.pop();
vis[u]=false;
for(int i=0;i<G[u].size();i++)
{ int s=G[u][i].to;
if(dis[s]>dis[u]+G[u][i].cost)
{dis[s]=dis[u]+G[u][i].cost;
if(!vis[s])
{ vis[s]=true;
q.push(s);}
//cout<<G[u][i].cost<<"*****"<<endl;
}
//cout<<s<<"***"<<endl;
}
}
return 0;
}
int main()
{ int m,n;
int a,b,c;
int t;
scanf("%d",&t);
while(t--)
{ for(int i=0;i<100007;i++)
G[i].clear();
scanf("%d%d",&m,&n);
for(int i=0;i<m-1;i++)
{scanf("%d%d",&a,&b);
add(a,b,1);
}
/*先求一个最远的点。然后在弄一遍。
*/
/*for(int i=1;i<=m;i++)
{for(int x=0;x<G[i].size();x++)
cout<<G[i][x].to<<" ";
cout<<endl;
}*/
int x=0;
int la=0;
spfa(1);
//cout<<">>"<<endl;
for(int i=1;i<=m;i++)
{ if(x<dis[i]&&dis[i]!=0x3f3f3f3f)
{ x=dis[i];
la=i;
}
}
//for(int i=1;i<=m;i++)
//cout<<dis[i]<<endl;
//cout<<la<<endl;
spfa(la);
x=0;
//for(int i=1;i<=m;i++)
//cout<<dis[i]<<endl;
for(int i=1;i<=m;i++)
{ if(x<dis[i])
x=dis[i];
}
x++;
int k;
for(int i=1;i<=n;i++)
{ scanf("%d",&k);
if(k<=x)
printf("%d\n",k-1);
else
printf("%d\n",(k-x)*2+x-1);}
}
return 0;
}