HDU 2586 How far away ?(LCA-tarjan算法会栈溢出@-@??)
c++递归的话会爆栈,自编写非递归46MS
G++递归不会爆78MS,tragedy!!!
#include <stdio.h>
#include <vector>
using namespace std;
#define MAXN 40001
#define MAXQ 201
int N,father[MAXN],ance[MAXN],dis[MAXN],res[MAXQ];
struct ENode
{
int adv,dis;
};
struct QNode
{
int adv,idx;
};
vector<ENode> adjlist[MAXN];
vector<QNode> query[MAXN];
bool visited[MAXN],color[MAXN];
struct SNode
{
int u,dist;
};
SNode stk[MAXN];
int top;
int find_mfs(int x)
{
int i,t;
for(i=x; father[i]>0; i=father[i]) ;
while(x!=i)
{
t=father[x];
father[x]=i;
x=t;
}
return i;
}
void merge_mfs(int x,int y)
{
int fx,fy;
fx=find_mfs(x);
fy=find_mfs(y);
if(fx==fy) return;
if(father[fx]>father[fy]) //-3>-4
{
father[fy]+=father[fx];
father[fx]=fy;
}
else
{
father[fx]+=father[fy];
father[fy]=fx;
}
}
void lca_tarjan(int uu,int dd)
{
// father[u]=-1;
top=-1;
stk[++top].u=uu;
stk[top].dist=dd;
bool first=true;
while(top!=-1)
{
int u,d;
size_t j;
u=stk[top].u;
d=stk[top].dist;
visited[u]=true;
if(first)
{
ance[u]=u;
visited[u]=true;
dis[u]=d;
}
else
{
merge_mfs(u,stk[top+1].u);
ance[find_mfs(u)]=u;
}
for(j=0; j<adjlist[u].size(); j++)
{
int v=adjlist[u][j].adv;
if(!visited[v])
{
stk[++top].u=v;
stk[top].dist=d+adjlist[u][j].dis;
first=true;
break;
}
}
if(j==adjlist[u].size())
{
--top;
first=false;
color[u]=true;
for(size_t k=0; k<query[u].size(); k++)
{
int w=query[u][k].adv;
if(color[w])
{
int x=ance[ find_mfs(w) ];
res[query[u][k].idx]=dis[u]+dis[w]-2*dis[x];
}
}
}
}
}
int main()
{
int T,Q,i,j,k,d;
ENode e;
QNode q;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&N,&Q);
for(i=1;i<=N;i++)
{
father[i]=-1;
visited[i]=false;
color[i]=false;
adjlist[i].clear();
query[i].clear();
}
for(k=0;k<N-1;k++)
{
scanf("%d %d %d",&i,&j,&d);
e.adv=j;
e.dis=d;
adjlist[i].push_back(e);
e.adv=i;
adjlist[j].push_back(e);
}
for(k=0;k<Q;k++)
{
scanf("%d %d",&i,&j);
q.adv=j;
q.idx=k;
query[i].push_back(q);
q.adv=i;
query[j].push_back(q);
}
lca_tarjan(1,0);
for(k=0;k<Q;k++) printf("%d\n",res[k]);
}
return 0;
}
//**************************************************************************************************
手动加栈
#include <stdio.h>
#include <vector>
using namespace std;
//加大栈空间,防止爆栈
#pragma comment(linker, "/STACK:102400000,102400000")
#define MAXN 40001
#define MAXQ 200
int N,father[MAXN],ance[MAXN],dis[MAXN],res[MAXQ];
struct ENode
{
int adv,dis;
};
struct QNode
{
int adv,idx;
};
vector<ENode> adjlist[MAXN];
vector<QNode> query[MAXN];
bool visited[MAXN],color[MAXN];
int find_mfs(int x)
{
int i,t;
for(i=x; father[i]>0; i=father[i]) ;
while(x!=i)
{
t=father[x];
father[x]=i;
x=t;
}
return i;
}
void merge_mfs(int x,int y)
{
int fx,fy;
fx=find_mfs(x);
fy=find_mfs(y);
if(fx==fy) return;
if(father[fx]>father[fy]) //-3>-4
{
father[fy]+=father[fx];
father[fx]=fy;
}
else
{
father[fx]+=father[fy];
father[fy]=fx;
}
}
void lca_tarjan(int u,int d)
{
// father[u]=-1;
ance[u]=u;
visited[u]=true;
dis[u]=d;
for(size_t j=0; j<adjlist[u].size(); j++)
{
int v=adjlist[u][j].adv;
if(visited[v]) continue;
lca_tarjan(v,d+adjlist[u][j].dis);
merge_mfs(u,v);
ance[find_mfs(u)]=u;
}
color[u]=true;
for(size_t k=0; k<query[u].size(); k++)
{
int w=query[u][k].adv;
if(color[w])
{
int x=ance[ find_mfs(w) ];
res[query[u][k].idx]=dis[u]+dis[w]-2*dis[x];
}
}
}
int main()
{
int T,Q,i,j,k,d;
ENode e;
QNode q;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&N,&Q);
for(i=1; i<=N; i++)
{
father[i]=-1;
visited[i]=false;
color[i]=false;
adjlist[i].clear();
query[i].clear();
}
for(k=0; k<N-1; k++)
{
scanf("%d %d %d",&i,&j,&d);
e.adv=j;
e.dis=d;
adjlist[i].push_back(e);
e.adv=i;
adjlist[j].push_back(e);
}
for(k=0; k<Q; k++)
{
scanf("%d %d",&i,&j);
q.adv=j;
q.idx=k;
query[i].push_back(q);
q.adv=i;
query[j].push_back(q);
}
lca_tarjan(1,0);
for(k=0; k<Q; k++) printf("%d\n",res[k]);
}
return 0;
}
浙公网安备 33010602011771号