codevs2370小机房的树

来源:互联网 发布:购买特价机票的软件 编辑:程序博客网 时间:2024/05/17 23:55

LCA练习;

/*小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上。有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力。已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力输入描述 Input Description    第一行一个n,接下来n-1行每一行有三个整数u,v, c 。表示节点 u 爬到节点 v 需要花费 c 的精力。第n+1行有一个整数m表示有m次询问。接下来m行每一行有两个整数 u ,v 表示两只虫子所在的节点输出描述 Output Description一共有m行,每一行一个整数,表示对于该次询问所得出的最短距离。*/#include<cstdio>#include<algorithm>#include<queue>#include<cstring>using namespace std;typedef long long ll;int fa[50010];int head[250000];int next[250000];int n,u,v,c,m;int dist[250000];int deep[250000];bool vis[250000];struct Edge{    int ff;    int to;    int d;}edge[250000];int tot;void add(int fff,int tt,int dd){    edge[++tot].ff = fff;    edge[tot].to=tt;    edge[tot].d=dd;    next[tot]=head[fff];    head[fff]=tot;}//    void dfs(int u,int f){fa[u] = f;//(令)F是U的爹 deep[u] = deep[f] + 1;//深度 儿子是爹深度+1 for(int i = head[u];i;i = next[i]){    int v = edge[i].to;    if(v == f)    { continue;} //搜重了...     else    {        dist[v] = dist[u] + edge[i].d;//跟到v的距离等于跟到u+(u到v的权         dfs(v,u);//v的父亲是u     }}}int ask_lca(int x,int y){if(deep[x] < deep[y])     {swap(x,y);}//调X while(deep[x] > deep[y])//把X提上来     {x = fa[x];}        while(x != y)//调到相等     {x = fa[x],y = fa[y];}return x;//找到公共祖先 }//int main(){ll ans;scanf("%d",&n);for(int i=1;i<=n-1;i++){    scanf("%d%d%d",&u,&v,&c);    add(u,v,c);    add(v,u,c);}scanf("%d",&m);deep[1] = 1;//1的爹是自己 dfs(0,200000);//令0的爹为2000000 for(int i=1;i<=m;i++){    int ans=0;    scanf("%d%d",&u,&v);    int xx=ask_lca(u,v);    ans=dist[u] + dist[v] - dist[xx] * 2;//从根节点xx,要走一段路,到XX的时候分叉,一股去u,一股去v,所以u->xx+v->x=1>u+1>v-(1>xx )*2     printf("%d\n",ans);//一个换行导致的血案 }return 0;}/*31 0 12 0 131 02 01 2*/
1 0
原创粉丝点击