HDU

来源:互联网 发布:西贝柳斯 Mac 软件下载 编辑:程序博客网 时间:2024/06/01 08:32

HDU - 4547 

思路: 这里可以分析出来,如果是从父节点跳到子节点,那么直接1步到位,如果不是,那么就先算跳到lca(a,b)的距离,如果lca是目标点,这就是结果,如果不是,还要+1。

注意特殊情况,坑死人。我用的map,如果上hash估计会更快一点。

#include <algorithm>#include <cstdio>#include <iostream>#include <cstring>#include <map>using namespace std;int t,n,m;int num = 1;map<string ,int> id;const int maxn = 1e5+10;struct node{    int to,w,next,f;    node(){}    node(int a,int b,int c){to = a; w = b; next = c;}}edge[maxn << 1], qu[maxn << 1];int h[maxn], hq[maxn], f[maxn], dis[maxn] ,vis[maxn], col[maxn] ,ans[maxn],  isRoot[maxn];int edgenum = 0, qnum = 0;void init(){    id.clear();    for(int i = 1; i <= maxn; i++)        h[i] = hq[i] = -1, f[i] = i, dis[i] = col[i] = isRoot[i] = 0;    edgenum = qnum = 0;    num = 1;}void add(int f,int t,int w){    edge[edgenum] = node(t , w , h[f]);    h[f] = edgenum++;}void addq(int f,int t,int id,int flag){    qu[qnum] = node(t , id , hq[f]);    qu[qnum].f = flag;    hq[f] = qnum++;}int getf(int i){   return i == f[i] ? i : f[i] = getf(f[i]);   }void join(int a,int b){    int i = getf(a), j = getf(b);    if(i != j)        f[j] = i;}void tarjan(int u){    for(int i = h[u] ; ~i; i = edge[i].next)    {        int v = edge[i].to;        if(!vis[v])        {            vis[v] = 1;            dis[v] = dis[u] + edge[i].w;            tarjan(v);            f[v] = u;            f[getf(u)] = u;            vis[v] = 0;        }    }    col[u] = 1;    for(int i = hq[u]; ~i; i = qu[i].next)    {        int v = qu[i].to, id = qu[i].w , flag = qu[i].f;        if(!col[v]) continue;        if(u == v) {    ans[id] = 0; continue;}        if(getf(v) == u)        {            if(flag) ans[id] = dis[v] - dis[u];            else ans[id] = 1;        }        else        {            if(flag) ans[id] = dis[v] - dis[getf(v)] + 1;            else ans[id] = dis[u] - dis[getf(v)] + 1;        }    }}int main(){    scanf("%d",&t);    char a[50],b[50];    while(t--)    {        scanf("%d%d",&n,&m);        if(n == 1)        {            for(int i = 0; i < m ; i++)            {                scanf("%s%s",&a,&b);                printf("0\n");            }            continue;        }        init();        for(int i = 1; i <= n-1 ; i++)        {            scanf("%s%s",a,b);            if(id.count(a) == 0)    id[a] = num++;            if(id.count(b) == 0)    id[b] = num++;            add(id[b],id[a],1);            isRoot[id[a]] ++;        }        for(int i = 1; i <= m; i++)        {            scanf("%s%s",&a,&b);            int ia = id[a], ib = id[b];            addq(ia,ib,i,0);    addq(ib,ia,i,1);        }        int r;        for(int i = 1; i < num; i++)            if(isRoot[i] == 0) {r = i;break;}        vis[r] = 1; dis[r] = 0;        tarjan(r);        vis[r] = 0;        for(int i = 1; i <= m ; i++)            printf("%d\n",ans[i]);    }    return 0;}


原创粉丝点击