Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 3708 | Accepted: 1315 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
7 6 1 6 13 E 6 3 9 E 3 5 7 S 4 1 3 N 2 4 20 W 4 7 2 S 3 1 6 1 4 2 6
Sample Output
13 3 36
Hint
Source
#include<stdio.h>//无向图,不知道根,离线查找两点间的距离,邻接表LCA
#include<string.h>
const int MAX=40005;
struct node
{
int dis,first;
}point[MAX];
struct road
{
int next,to,dis;
}rd[MAX*2],que[MAX*2];
int p[MAX],link[MAX],res[MAX];
bool vis[MAX];
void init(int n)//并查集
{
for(int i=0;i<=n;i++)
{
p[i]=i;
link[i]=-1;
point[i].first=-1;
res[i]=0;
vis[i]=false;
}
}
int find(int x)
{
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
}
int Union(int a,int b)
{
a=find(a);
b=find(b);
p[b]=a;
return a;
}
void insertR(int from,int to,int len,int& n)
{
rd[n].to=to;
rd[n].dis=len;
rd[n].next=point[from].first;
point[from].first=n++;
}
void insertQ(int from,int to,int index,int& n)
{
que[n].to=to;
que[n].dis=index;
que[n].next=link[from];
link[from]=n++;
}
void lca(int pos,int dis)
{
int p;
point[pos].dis=dis;
vis[pos]=true;
for(int i=point[pos].first;i!=-1;i=rd[i].next)
{
if(!vis[rd[i].to])
{
lca(rd[i].to,dis+rd[i].dis);
Union(pos,rd[i].to);
}
}
for(int i=link[pos];i!=-1;i=que[i].next)
{
if(vis[que[i].to])
{
p=find(que[i].to);
res[que[i].dis]=dis+point[que[i].to].dis-2*point[p].dis;//que[i].dis表示的是询问的序号
}
}
}
int main()
{
int n,m,from,to,len,rn,qn,k;
char c;
while(scanf("%d%d",&n,&m)!=EOF)
{
rn=0,qn=0;
init(n);//如果是多组数据,那么初始化要注意
for(int i=0;i<m;i++)
{
scanf("%d %d %d %c",&from,&to,&len,&c);
insertR(from,to,len,rn);//无向图
insertR(to,from,len,rn);
}
scanf("%d",&k);
for(int i=0;i<k;i++)
{
scanf("%d %d",&from,&to);
insertQ(from,to,i,qn);
insertQ(to,from,i,qn);
}
vis[1]=true;//假设一为根,如果是多组数组,注意数组的初始化
lca(1,0);
for(int i=0;i<k;i++) printf("%d/n",res[i]);
}
return 0;
}