hdu2586[lca]
tarjon 是离线的算法, 在线的话会有倍增法和rmq,其实这2个方法有一曲同工之妙
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn=100000+123; #define forg(p,x) for(p=x; ~p; p=edge[p].next) struct Edge{ int v, w, next; }edge[maxn*2]; int head[maxn], cnt; // for graph void addedge(int u, int v, int w) { edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } int fath[maxn], used[maxn]; // for dis-union struct query{ int a, b, lca; }list[maxn]; // for struct Ans{ int v, idx; }; vector<Ans> ques[maxn]; // for every query int find (int x) { return fath[x]=(x==fath[x]? x: find(fath[x])); } inline void merge (int x, int y) { fath[find(y)]=find(x); } int dis[maxn]; void dfs(int u, int r) { for (int p=head[u]; ~p; p=edge[p].next) { const int &v=edge[p].v; if(r==v)continue; dis[v]=dis[u]+edge[p].w; dfs(v, u); } } void LCA(int u, int r) { int p; fath[u]=u; //printf("u===%d\n", u); forg(p, head[u]) { const int &v=edge[p].v; if(v==r)continue; LCA(v, u); merge(u, v);///u, v 顺序固定,必须将子合并到父,按秩合并不是和重要 } //printf("%d %d\n", anc[u], fath[u]); for(int i=0; i<ques[u].size(); ++i) { const int &v=ques[u][i].v; if(~fath[v]) list[ques[u][i].idx].lca=fath[find(v)]; } } bool isroot[maxn]; void init(int x) { for (int i=0; i<x; ++i) { ques[i].clear(); fath[i]=i; } memset (head, -1, sizeof(head)); cnt=0; } int main () { char op[10]; int n, m; int cas; scanf("%d", &cas); while (cas--) { scanf("%d%d", &n, &m); init(n); for (int i=1; i<n; ++i) { int a, b, c; scanf("%d %d %d", &a, &b, &c, op); a--; b--; addedge(a, b, c); addedge(b, a, c); } for (int i=0; i<m; ++i) { int a, b; scanf("%d%d", &a, &b); a--; b--; list[i].a=a; list[i].b=b; Ans tmp; tmp.v=b; tmp.idx=i; ques[a].push_back(tmp); tmp.v=a; ques[b].push_back(tmp); } //puts("!"); dfs(0, -1); LCA(0, -1); for (int i=0; i<m; ++i) { printf("%d\n", dis[list[i].a]+dis[list[i].b]-2*dis[list[i].lca]); } } return 0; }
zoj 2615 cells 非递归的tarjon.
yes no打错了。 wa了2次才看出来
#include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <vector> #define copy(a, b) memcpy(a, b, sizeof(a)); #define clean(a, x) memset (a, x, sizeof(a)); using namespace std; const int maxn=300000+123; int anc[20000000+123]; #define vex edge[p].v struct Edge{int v, next;}edge[2*maxn]; int head[maxn], cnt; void addedge(int u, int v){ //printf("%d %d\n", u, v); edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; } int fath[maxn], used[maxn]; struct Ans{ int v, idx; }; vector< Ans > ques[maxn]; int find (int x) { return fath[x]=(x==fath[x]? x: find(fath[x])); } inline void merge (int x, int y) { fath[find(y)]=find(x); } stack<int> S; int cur[maxn], pre[maxn]; int res[1000000+123]; void LCA(int rt) { S.push(0); fath[0]=0; pre[0]=-1; copy(cur, head); while (!S.empty()) { bool flag=false; int u=S.top(); ///printf("%d\n", u); for (int p=cur[u]; ~p; p=edge[p].next) { S.push(vex); fath[vex]=vex; pre[vex]=u; flag=true; cur[u]=edge[p].next; break; } if(flag)continue; ///printf("%d is over\n", u); S.pop(); for (int i=0; i<ques[u].size(); ++i) { const Ans &a=ques[u][i]; if(~fath[a.v]) res[a.idx]=fath[find(a.v)]; ///printf("anc==%d %d\n", res[a.idx], a.idx); } if(~pre[u]) { merge(pre[u], u); } } } void init() { clean(head, -1); cnt=0; } int qa[1000000+123]; int main() { int cas; scanf("%d", &cas); for (int I=1; I<=cas; ++I) { int n; scanf("%d", &n); int num=0; init(); for (int i=0; i<n; ++i) { ques[i].clear(); fath[i]=i; int sc; scanf("%d", &sc); for (int j=0; j<sc; ++j) { num++; // addedge(i, num); if(num<n)addedge(i, num); else anc[num-n]=i; } } //printf("num==%d\n", num); int m; scanf("%d", &m); for (int i=0; i<m; ++i) { int a, b; scanf("%d%d", &a, &b); if(a!=b)qa[i]=a; else qa[i]=-1; if(a>=n)a=anc[a-n]; if(b>=n)b=anc[b-n]; Ans tmp; tmp.v=b; tmp.idx=i; ques[a].push_back(tmp); tmp.v=a; ques[b].push_back(tmp); } LCA(0); if(I!=1)printf("\n"); printf("Case %d:\n", I); for (int i=0; i<m; ++i) { ///printf("%d %d ", qa[i], res[i]); if(qa[i]==res[i])puts("Yes"); else puts("No"); } } return 0; } /* 2 6 3 2 1 1 1 2 10 0 1 2 4 3 5 1 8 6 9 8 9 5 5 5 9 0 9 9 10 5 2 0 3 0 1 4 2 6 1 6 2 3 3 5 */