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;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- android toolbar 设置应用栏 [U01]
- 521. Longest Uncommon Subsequence I
- 关于bit位域和大小端的理解
- 操作系统学习笔记
- 常用DOS命令大全
- HDU
- 基于redis分布式缓存实现(新浪微博案例)
- <一>、TensorFlow环境搭建
- 从云大会谈谈云计算“关键”技术趋势
- Android应用程序访问硬件驱动(JNI方式)
- Java面试题
- angular4 引入bootstrap
- 1011. World Cup Betting (20)
- JSP中页面传值方法