Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 3709 | Accepted: 1316 | |
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>
#include<vector>
using namespace std;
const int MAX=40005;
struct node
{
node(int vv=0,int vval=0):v(vv),val(vval) {}
int v,val;
};
int f[MAX],vis[MAX];
vector<node> tree[2*MAX],Qes[2*MAX];
int d[MAX],res[MAX];
void init(int n)
{
for(int i=1; i<=n; i++)
{
f[i]=i;//用于并查集记录父亲节点
vis[i]=0;//是否被访问
tree[i].clear();//清空
Qes[i].clear();
res[i]=0;
}
}
int find(int n) //查找函数,并压缩路径
{
if(n!=f[n]) f[n]=find(f[n]);
return f[n];
}
int Union(int x,int y) //合并函数,如果属于同一分支则返回0,成功合并返回1
{
int a=find(x),b=find(y);
f[y]=x;
return b;
}
void LCA(int u,int dis)
{
d[u]=dis;
vis[u]=1;
int size=tree[u].size();
for(int i=0; i<size; i++)
if(!vis[tree[u][i].v])
{
LCA(tree[u][i].v,dis+tree[u][i].val);
Union(u,tree[u][i].v);
}
size=Qes[u].size();
for(int i=0; i<size; i++) //如果已经访问了问题节点,就可以返回结果了.
{
if(vis[Qes[u][i].v])
{
int p=find(Qes[u][i].v);
res[Qes[u][i].val]=dis+d[Qes[u][i].v]-2*d[p];
}
}
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
init(n);
int s,t,c;
char ch;
for(int i=1; i<=m; i++)
{
scanf(" %d %d %d %c",&s,&t,&c,&ch);
tree[s].push_back(node(t,c));
tree[t].push_back(node(s,c));
}
int k;
scanf("%d",&k);
for(int i=1;i<=k;i++)
{
scanf("%d%d",&s,&t);//这里可以输入多组询问
Qes[s].push_back(node(t,i));//相当于询问两次
Qes[t].push_back(node(s,i));
}
LCA(1,0);
for(int i=1;i<=k;i++) printf("%d/n",res[i]);
}
return 0;
}