HDU 2874 Connections between cities 离线LCA

来源:互联网 发布:零起点学通c语言光盘 编辑:程序博客网 时间:2024/06/01 08:29

题意:有n个点m条无向边,每一条边都有权值,有q次询问,每次问两点之间的距离。


想法:因为有的城市可能没有连接,所以整个图可能会分成几个块,所以如果是两个不同块的那么肯定是无法互联的,然后其他的点的距离用离线LCA即可。


#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int N=10000+2;const int M=1000000+2;struct node{    int to,next;    int w;};struct node G[N*2];struct nodeQ{    int to,next;    int id;};struct nodeQ QG[M*2];int head[N],cnt,headQ[N],cntQ;int father[N],dis[N],vis[N];int ans[M];void Init(int n){    memset(head,-1,sizeof(head));    memset(headQ,-1,sizeof(headQ));    cnt=0;cntQ=0;    for(int i=1;i<=n;i++)    {        father[i]=i;    }    memset(dis,0,sizeof(dis));    memset(vis,0,sizeof(vis));    memset(ans,-1,sizeof(ans));}void add(int a,int b,int c){    G[cnt].to=b;    G[cnt].w=c;    G[cnt].next=head[a];    head[a]=cnt++;}void addQ(int a,int b,int c){    QG[cntQ].to=b;    QG[cntQ].id=c;    QG[cntQ].next=headQ[a];    headQ[a]=cntQ++;}int find_set(int x){    if(x!=father[x])    father[x]=find_set(father[x]);    return father[x];}void union_set(int x,int y){    x=find_set(x);    y=find_set(y);    if(x==y) return;    father[y]=x;}void lca(int u,int w,int root){    vis[u]=root;    dis[u]=w;    for(int i=head[u];i+1;i=G[i].next)    {        int v=G[i].to;        int len=G[i].w;        if(vis[v]) continue;        lca(v,w+len,root);        union_set(u,v);    }     for(int i=headQ[u];i+1;i=QG[i].next)    {        int v=QG[i].to;        if(vis[v]==root)        {            ans[QG[i].id]=dis[u]+dis[v]-2*dis[find_set(v)];        }    }}int main(){    int m,n,q;    while(~scanf("%d%d%d",&n,&m,&q))    {        Init(n);        while(m--)        {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            add(a,b,c);            add(b,a,c);        }        for(int i=1;i<=q;i++)        {            int a,b;            scanf("%d%d",&a,&b);            addQ(a,b,i);            addQ(b,a,i);        }        for(int i=1;i<=n;i++)        {            if(!vis[i])            {                lca(i,0,i);            }        }        for(int i=1;i<=q;i++)        {            if(ans[i]==-1) printf("Not connected\n");            else printf("%d\n",ans[i]);        }    }    return 0;}

0 0
原创粉丝点击