uestc 1717 Journey

来源:互联网 发布:ubuntu如何切换输入法 编辑:程序博客网 时间:2024/06/05 16:24
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <set>#include <vector>using namespace std;const int N=100009;int n,m;int a,b,c,x,y;int len[N];int get[N];int vis[N],fa[N];vector<pair<int,int> > v[N],need[N];void dfs(int x,int f,int L)//处理出每个点到根的距离{    vis[x]=1;    len[x]=L;    for(int i=0;i<v[x].size();i++)    {        int y=v[x][i].first;        if(y==f)continue;        dfs(y,x,L+v[x][i].second);        fa[y]=x;    }}void dfs2(int x,int f,int id)//vis[x]=id表示节点x对应环上的点id{    vis[x]=id;    for(int i=0;i<v[x].size();i++)    {        int y=v[x][i].first;        if(y==f)continue;        dfs2(y,x,id);    }}void init(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)    {        v[i].clear();        fa[i]=i;        vis[i]=0;    }    for(int i=1;i<=n-1;i++)    {        scanf("%d%d%d",&a,&b,&c);        v[a].push_back(make_pair(b,c));        v[b].push_back(make_pair(a,c));    }    scanf("%d%d%d",&a,&b,&c);    dfs(b,-1,0);//以b为根建树    fa[b]=-1;    if(c>=len[a])//如果加入的边比原先b-a的距离大,答案全为零    {        for(int i=1;i<=m;i++)        {            scanf("%d%d",&x,&y);            puts("0");        }    }    else    {        int x=a;        int id=3;        do //由a遍历到b,将非环上的点对应成环上的点        {            vis[x]=2;            for(int i=0;i<v[x].size();i++)            {                int y=v[x][i].first;                if(y==fa[x]||vis[y]==2)continue;                dfs2(y,x,id);            }            get[id]=x;//get[id]=x表示vis[y]=id的点都对应点x            id++;            x=fa[x];        }while(x!=-1);                for(int i=1;i<=m;i++)        {            scanf("%d%d",&x,&y);            if(vis[x]!=2)  x=get[vis[x]];//如果不是环上的点,找到对应点            if(vis[y]!=2)   y=get[vis[y]];            if(len[y]<len[x])  swap(x,y);                        int tmp1=len[y]-len[x];            int tmp2=len[x]+c+len[a]-len[y];//比较绕新加入的边是否可以减少距离            if(tmp2<tmp1)            {                printf("%d\n",tmp1-tmp2);            }            else            {                puts("0");            }        }    }}int main(){    int T;    scanf("%d",&T);    for(int ii=1;ii<=T;ii++)    {        printf("Case #%d:\n",ii);        init();    }return 0;}

原创粉丝点击