zoj 3195 Design the city(LCA)

来源:互联网 发布:mac如何打#键 编辑:程序博客网 时间:2024/05/22 13:35


zoj 3195 Design the city


树上三点最短距离,分别求两点间最短距离,再求和除以2


#include<cstdio>#include<cstring>#include<vector>using namespace std;#define MAXN 50005#define MAXM 70005struct tnode{    int v,d;    tnode(int v=0,int d=0):v(v),d(d){}};struct qnode{    int v,id;    qnode(int v=0,int id=0):v(v),id(id){}};vector<tnode> t[MAXN];vector<qnode> q[MAXN];int ans[MAXM],fa[MAXN],dis[MAXN];bool vis[MAXN];int n,m;void ini(){    for(int i=0;i<n;i++)    {        t[i].clear();        q[i].clear();        vis[i]=false;        fa[i]=i;    }}int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);}void lca(int u){    vis[u]=true;    for(int i=0;i<q[u].size();i++)    {        int v=q[u][i].v;        if(vis[v])            ans[q[u][i].id]+=dis[u]+dis[v]-2*dis[find(v)];    }    for(int i=0;i<t[u].size();i++)    {        int v=t[u][i].v;        if(!vis[v])        {            dis[v]=dis[u]+t[u][i].d;            lca(v);            fa[v]=u;        }    }}int main(){    bool flag=false;    while(scanf("%d",&n)!=EOF)    {        if(flag) printf("\n");        else flag=true;        ini();        int u,v,d;        for(int i=0;i<n-1;i++)        {            scanf("%d%d%d",&u,&v,&d);            t[u].push_back(tnode(v,d));            t[v].push_back(tnode(u,d));        }        scanf("%d",&m);        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&u,&v,&d);            ans[i]=0;            q[u].push_back(qnode(v,i));            q[v].push_back(qnode(u,i));            q[u].push_back(qnode(d,i));            q[d].push_back(qnode(u,i));            q[v].push_back(qnode(d,i));            q[d].push_back(qnode(v,i));        }        dis[1]=0;        lca(1);        for(int i=0;i<m;i++)            printf("%d\n",ans[i]/2);    }    return 0;}


0 0
原创粉丝点击