记录编号 |
263371 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[USACO Feb04]距离咨询 |
最终得分 |
100 |
用户昵称 |
Marvolo |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
1.027 s |
提交时间 |
2016-05-24 20:33:46 |
内存使用 |
3.56 MiB |
显示代码纯文本
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int n,m,i,a,b,c,k;
char qq,ww;
int fl[40010],f[40010]; //到父亲节点距离和父亲节点
int s[40010],d[40010],zj[40010]; //存放节点和一个指针
int fa[40010];
bool v[40010];
vector <int> l[40010],ll[40010]; //l,ll存初始图
vector <int> son[40010]; //son存子节点
vector <int> w[40010]; //存放询问的节点
vector <int> ans[40010]; //存放询问的节点的答案
inline void maketree(int x){
int i=0;
v[x]=1;
for (i=0;i<=l[x].size()-1;i++)
if (not v[l[x][i]]){
son[x].push_back(l[x][i]); f[l[x][i]]=x;
fl[l[x][i]]=ll[x][i]; maketree(l[x][i]);}
return;
} //DFS建树
inline int read(){
int x=0,p=0;
while (p-48<0||p-48>9) p=getchar();
while (p-48>=0&&p-48<=9) {x=x*10+p-48; p=getchar();}
return x;
} //快速读入
inline int find(int x){return (x==fa[x])?x:fa[x]=find(fa[x]);}
inline int query(int a,int b,int lca){
int an=0,q=0,e=0;
q=a; e=b;
while (q!=lca) an+=fl[q],q=f[q];
while (e!=lca) an+=fl[e],e=f[e];
return an;
} //计算树上两点间距离
inline void tarjan(int p){
int i;
if (son[p].size()!=0)
for (i=0;i<=son[p].size()-1;i++)
if (not v[son[p][i]]) {
tarjan(son[p][i]); fa[son[p][i]]=p;}
v[p]=1;
if (w[p].size()!=0)
for (i=0;i<=w[p].size()-1;i++)
if (v[w[p][i]]) ans[p][i]=query(p,w[p][i],find(w[p][i]));
return;
} //Tarjan求LCA
void work(){
int i,q,e;
k=read();
for (i=1;i<=k;i++){
s[i]=read(); d[i]=read();
w[s[i]].push_back(d[i]); w[d[i]].push_back(s[i]);
ans[s[i]].push_back(0); ans[d[i]].push_back(0);}
memset(v,0,sizeof(v));
for (i=1;i<=n;i++) fa[i]=i;
tarjan(1);
for (i=1;i<=k;i++){
if (ans[s[i]][zj[s[i]]]!=0) printf("%d\n",ans[s[i]][zj[s[i]]]);
else printf("%d\n",ans[d[i]][zj[d[i]]]);
zj[s[i]]++; zj[d[i]]++;}
return;
}
int main(){
freopen("dquery.in","r",stdin);
freopen("dquery.out","w",stdout);
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++){
scanf("%d%d%d%c%c",&a,&b,&c,&qq,&ww);
l[a].push_back(b); ll[a].push_back(c);
l[b].push_back(a); ll[b].push_back(c);}
for (i=1;i<=n;i++) f[i]=i;
maketree(1); //建树
work();
return 0;
}