Navigation Nightmare POJ - 1984
考察: 带权并查集
思路:
设置东西方向和南北方向两个数组,其他就和之前的题目一样,但是要注意我们压缩路径的时候要把东西和南北距离都压缩
1 #include <iostream> 2 using namespace std; 3 const int N = 40010; 4 int p[N],d[N],E[N]; 5 struct road{ 6 int a,b,l; 7 char dir[2]; 8 }road[N]; 9 int findf(int x) 10 { 11 if(x!=p[x]){ 12 int t = findf(p[x]); 13 E[x]+=E[p[x]]; 14 d[x]+=d[p[x]]; 15 p[x] = t; 16 } 17 return p[x]; 18 } 19 int main() 20 { 21 // freopen("in.txt","r",stdin); 22 int n,m,k; 23 while(scanf("%d%d",&n,&m)!=EOF) 24 { 25 fill(d,d+N,0); fill(E,E+N,0); 26 for(int i=1;i<=N-10;i++) p[i] = i; 27 for(int i=1;i<=m;i++) 28 scanf("%d%d%d%s",&road[i].a,&road[i].b,&road[i].l,road[i].dir); 29 scanf("%d",&k); 30 int j = 1; 31 while(k--){//根据东南西北逐个方向判断即可 32 int a,b,s; 33 scanf("%d%d%d",&a,&b,&s); 34 for(int i=j;i<=s;i++){ 35 int px = findf(road[i].a); int py = findf(road[i].b); 36 if(px!=py){ 37 p[px] = py;//错点:没有更新不同的距离 38 if(road[i].dir[0]=='E'){ 39 E[px] = E[road[i].b]-E[road[i].a]-road[i].l; 40 d[px] = d[road[i].b]-d[road[i].a]; 41 }else if(road[i].dir[0]=='W'){ 42 E[px] = E[road[i].b]+road[i].l-E[road[i].a]; 43 d[px] = d[road[i].b]-d[road[i].a]; 44 }else if(road[i].dir[0]=='S'){ 45 d[px] = d[road[i].b]-road[i].l-d[road[i].a]; 46 E[px] = E[road[i].b]-E[road[i].a]; 47 }else if(road[i].dir[0]=='N'){ 48 d[px] = d[road[i].b]-d[road[i].a]+road[i].l; 49 E[px] = E[road[i].b]-E[road[i].a]; 50 } 51 }else continue; 52 } 53 j = s+1; 54 int pa = findf(a); int pb = findf(b); 55 if(pa==pb) printf("%d\n",abs(E[b]-E[a])+abs(d[b]-d[a])); 56 else printf("-1\n"); 57 } 58 } 59 return 0; 60 }