POJ 1986 RMQ+LCA

来源:互联网 发布:淘宝女人秋装 编辑:程序博客网 时间:2024/06/05 05:27

题意

给一堆点,一堆边,问一个点到另一个点的最短距离。

题解

其实就是LCA的模板题,只不过题目好坑啊,数据范围在1984这道题里,看错了数据范围,然后一直RE。

代码

#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<string>#include<set>#include<map>#include<bitset>#include<stack>#include<string>#pragma comment(linker,"/STACK:102400000,102400000")#define UP(i,l,h) for(int i=l;i<h;i++)#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)#define W(a) while(a)#define MEM(a,b) memset(a,b,sizeof(a))#define LL long long#define INF 0x3f3f3f3f#define MAXN 40010#define MOD 1000000007#define EPS 1e-3using namespace std;struct Node {    int to,w;    Node(int to,int w):to(to),w(w) {}};int n,m,k;vector<Node> vc[MAXN];int dep[MAXN<<1],ds[MAXN],vis[MAXN<<1],id[MAXN];int d[MAXN<<1][20];void dfs(int u,int p,int deep,int dis) {    id[u]=k;    ds[u]=dis;    dep[k]=deep;    vis[k++]=u;    int sz=vc[u].size();    UP(i,0,sz) {        Node nd=vc[u][i];        if(nd.to==p)            continue;        dfs(nd.to,u,deep+1,dis+nd.w);        dep[k]=deep;        vis[k++]=u;    }}void rmq_init() {    UP(i,0,k) {        d[i][0]=i;    }    for(int j=1; (1<<j)<=k; j++) {        for(int i=0; i+(1<<j)-1<k; i++) {            if(dep[d[i][j-1]]>dep[d[i+(1<<(j-1))][j-1]])                d[i][j]=d[i+(1<<(j-1))][j-1];            else                d[i][j]=d[i][j-1];        }    }}int rmq(int l,int r) {    int k=0;    W(1<<(k+1)<=r-l+1) {        k++;    }    if(dep[d[l][k]]>dep[d[r-(1<<k)+1][k]])        return d[r-(1<<k)+1][k];    else        return d[l][k];}int main() {    W(~scanf("%d%d",&n,&m)) {        MEM(dep,0);        MEM(ds,0);        MEM(vis,0);        MEM(id,-1);        MEM(d,0);        MEM(vc,0);        char c[5];        int a,b,w;        k=0;        UP(i,0,m) {            scanf("%d%d%d%s",&a,&b,&w,c);            vc[a].push_back(Node(b,w));            vc[b].push_back(Node(a,w));        }        UP(i,1,n+1) {            if(id[i]==-1) {                dfs(i,0,0,0);            }        }        rmq_init();        int kk;        scanf("%d",&kk);        W(kk--) {            scanf("%d%d",&a,&b);            if(id[a]>id[b])                swap(a,b);            int x=rmq(id[a],id[b]);            printf("%d\n",ds[a]+ds[b]-2*ds[vis[x]]);        }    }}/*5 41 2 1000 E2 3 1000 E3 4 1000 E4 5 1000 E35 14 21 5*/
原创粉丝点击