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;
}

posted @ 2010-08-19 21:45  菜到不得鸟  阅读(684)  评论(0)    收藏  举报