标签:
一,首先就是比较简单(弱智的我看了将近半小时)的tarjan了;我一直在纠结于一个地方就是如果要求的是8和5的话我一直以为他求出来的最近公共祖先是1...但不是,因为8和5都属于2,在遍历2的时候就求出来了,同理要是求8和9的话在遍历4的时候也都求出来了。这一步我想了很久真的怀疑自己的智商。不过至少看懂了。。。
hdu2586:
#include<cstdio> #include<cstring> #include<vector> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) const int nmax=40005; vector<int>v[nmax],w[nmax],q[nmax],c[nmax]; int f[nmax],d[nmax],ans[nmax],vis[nmax]; int find(int x){ return f[x]==x?x:f[x]=find(f[x]); } int Union(int x,int y){ int p=find(x); int q=find(y); if(p!=q) f[y]=x; } int read(){ int x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)){ x=x*10+c-‘0‘; c=getchar(); } return x; } void tarjan(int cur,int val){ vis[cur]=1; d[cur]=val; for(int i=0;i<v[cur].size();i++){ int tmp=v[cur][i]; if(vis[tmp]) continue; tarjan(tmp,val+w[cur][i]); Union(cur,tmp); } for(int i=0;i<q[cur].size();i++){ int tmp=q[cur][i]; if(vis[tmp]){ ans[c[cur][i]]=d[cur]+d[tmp]-2*d[find(tmp)]; } } } int main(){ int cnt; cnt=read(); while(cnt--){ int n=read(),m=read(); rep(i,n){ v[i].clear(); w[i].clear(); q[i].clear(); c[i].clear(); f[i]=i; vis[i]=0; d[i]=0; } rep(i,n-1){ int u=read(),o=read(),e=read(); v[u].push_back(o); w[u].push_back(e); v[o].push_back(u); w[o].push_back(e); } rep(i,m){ int o=read(),e=read(); q[o].push_back(e); q[e].push_back(o); c[o].push_back(i); c[e].push_back(i); } tarjan(1,0); rep(i,m) printf("%d\n",ans[i]); } return 0; }
标签:
原文地址:http://www.cnblogs.com/20003238wzc--/p/4852295.html