POJ1986 DistanceQueries 最近公共祖先LCA 离线算法Tarjan

来源:互联网 发布:js点击小图切换大图 编辑:程序博客网 时间:2024/05/19 21:00

这道题与之前那两道模板题不同的是,路径有了权值,而且边是双向的,root已经给出来了,就是1,(这个地方如果还按之前那样来计算入度是会出错的。数据里会出现多个root。。。数据地址可以在poj的discuss板块看到)。两个节点之间的距离,可以这样处理:先处理出每个节点i到根的距离dist[i],则节点a,b之间的距离就是dist[a]+dist[b]-2*dist[LCA(a,b)],或者是在LCA的过程中加一个形式变量来传递距离值(目测这样效率会更高)。我一开始是想的仅传递每层的距离,具体怎样记不清了,结果样例就华丽丽地wa了。个人认为这个题目描述真心不爽。最后那个方向字符在这个题中没用。

#include<cstdio>#include<vector>#include<string>//sba,just predeal the distance between every node and the root.and the dist[u][v]=dist[u][root]+dist[v][root]-2*dist[x][root]using namespace std;const int MAXN=50000;const int MAXQUERY=100100;int n,m,root=1;struct node{    int v,dis;    node(){v=0;dis=0;}};int ansque[MAXQUERY];int father[MAXN];//i's ancestor and the distance between the son and the ancestorvector<node>map[MAXN];vector<node>query[MAXN];int dist[MAXN];//i -->rootbool visit[MAXN],visit2[MAXN];int getfather(int v){    if(father[v]==v)return v;    return father[v]=getfather(father[v]);}void aunion(int u,int v){    int fu=father[u],fv=father[v],di;    father[fv]=fu;}void LCA(int id,int distance){    int len=map[id].size();    int son;    visit2[id]=1;    dist[id]=distance;    for(int i=0;i<len;i++){        son=map[id][i].v;        if(!visit2[son]){            LCA(son,distance+map[id][i].dis);            aunion(id,son);        }    }    visit[id]=true;    len=query[id].size();    for(int i=0;i<len;i++){        son=query[id][i].v;        if(visit[son]){            ansque[query[id][i].dis]=dist[id]+dist[son]-2*dist[father[getfather(son)]];            //mark        }    }}int main(){    while(scanf("%d%d",&n,&m)!=EOF){//attention        //at the begining,we'd better to initialize all the vars        int x,y,l;        char a;        node b;        for(int i=0;i<=n;i++){            map[i].clear();//the mothod of the initialization of queue            query[i].clear();            father[i]=i;            visit[i]=0;            visit2[i]=0;            ansque[i]=0;            dist[i]=0;        }        while(m--){            scanf("%d %d %d %c",&x,&y,&l,&a);//only father            b.v=y;b.dis=l;            map[x].push_back(b);            b.v=x;            map[y].push_back(b);        }        scanf("%d",&m);        node tmp2;        for(int i=0;i<m;i++){            scanf("%d%d",&x,&y);            tmp2.v=y;tmp2.dis=i;            query[x].push_back(tmp2);            tmp2.v=x;            query[y].push_back(tmp2);        }        LCA(1,0);        for(int i=0;i<m;i++)            printf("%d\n",ansque[i]);    }    return 0;}

 

0 0
原创粉丝点击