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
*/