标签:acm algorithm poj lca tarjan
| Time Limit: 2000MS | Memory Limit: 30000KB | 64bit IO Format: %I64d & %I64u |
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
题意:在一棵树上,查询(u,v)最短距离。
分析:LCA+tarjan离线算法,模板题。
ps:最近写LCA用的都是数组来存边,感觉比vector好用多了~~~~~
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11131
代码清单:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<string>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
const int maxn = 40000 + 5;
const int maxv = 40000 + 5;
const int maxq = 10000 + 5;
struct MAX{
int v,d;
MAX(){}
MAX(int v,int d){
this -> v = v;
this -> d = d;
}
};
struct Q{ int v,id,next; }quary[2*maxq];
struct e{ int v,dis,next; }graph[2*maxn];
int n,m,q;
int a,b,c;
char s[3];
int father[maxn];
bool vis[maxn];
int ans[maxq];
int color[maxn];
int depth[maxn];
int nume,numq;
int heade[maxn];
int headq[maxn];
void init(){
for(int i=1;i<=maxn;i++) father[i]=i;
memset(ans,-1,sizeof(ans));
memset(color,0,sizeof(color));
memset(depth,0,sizeof(depth));
memset(vis,false,sizeof(vis));
memset(graph,0,sizeof(graph));
memset(quary,0,sizeof(quary));
memset(heade,-1,sizeof(heade));
memset(headq,-1,sizeof(headq));
nume=numq=0;
}
void add_E(int u,int v,int dis){
graph[nume].v=v;
graph[nume].dis=dis;
graph[nume].next=heade[u];
heade[u]=nume++;
}
void add_Q(int u,int v,int id){
quary[numq].v=v;
quary[numq].id=id;
quary[numq].next=headq[u];
headq[u]=numq++;
}
void input(){
for(int i=0;i<m;i++){
scanf("%d%d%d%s",&a,&b,&c,s);
add_E(a,b,c);
add_E(b,a,c);
}
scanf("%d",&q);
for(int i=1;i<=q;i++){
scanf("%d%d",&a,&b);
add_Q(a,b,i);
add_Q(b,a,i);
}
}
int Find(int x){ return x!=father[x] ? father[x]=Find(father[x]) : father[x]; }
void tarjan(int u){
color[u]=1;
vis[u]=true;
for(int i=headq[u];i!=-1;i=quary[i].next){
int ID=quary[i].id;
if(ans[ID]!=-1) continue;
int v=quary[i].v;
if(color[v]==0) continue;
if(color[v]==1) ans[ID]=depth[u]-depth[v];
if(color[v]==2) ans[ID]=depth[u]+depth[v]-2*depth[Find(v)];
}
for(int i=heade[u];i!=-1;i=graph[i].next){
int vv=graph[i].v;
int dis=graph[i].dis;
if(!vis[vv]){
depth[vv]=depth[u]+dis;
tarjan(vv);
color[vv]=2;
father[vv]=u;
}
}
}
void solve(){
tarjan(1);
for(int i=1;i<=q;i++){
printf("%d\n",ans[i]);
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
init();
input();
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ_1986_Distance Queries(LCA+tarjan)
标签:acm algorithm poj lca tarjan
原文地址:http://blog.csdn.net/jhgkjhg_ugtdk77/article/details/47266515