卧薪尝胆,厚积薄发。
USACO2004FEB Navigation Nightmare 导航噩梦
Date: Sun Oct 21 11:11:01 CST 2018 In Category: NoCategory

Description:

有一个图,保证任意两点间仅有一条路径,每次给出两个农场的位置关系,或者求两个点间的曼哈顿距离。
$1\leqslant n\leqslant 400000$

Solution:

带权并查集,维护到联通块根节点的距离向量。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
inline int getc()
{
register char c = getchar();
while(c != 'N' && c != 'S' && c != 'W' && c != 'E')c = getchar();
if(c == 'N')return 1;
if(c == 'S')return 2;
if(c == 'W')return 3;
if(c == 'E')return 4;
}
inline int read()
{
register int res = 0,f = 1;
register char c = getchar();
while(!isdigit(c))
{
if(c == '-')f = -1;
c = getchar();
}
while(isdigit(c))
{
res = (res << 1) + (res << 3) + c - '0';
c = getchar();
}
return res * f;
}
int n,m,p;
#define MAXN 400010
#define MAXQ 100010
struct query
{
int tim,type;
int a,b,d,f;
int id;
int ans;
}q[MAXN + MAXQ];
int tot = 0;
bool cmp(query a,query b)
{
if(a.tim == b.tim)return a.type < b.type;
else return a.tim < b.tim;
}
bool cmp_id(query a,query b){return a.id < b.id;}
int f[MAXN],x[MAXN],y[MAXN];
int find(int k)
{
if(k == f[k])return k;
int rt = find(f[k]);
x[k] += x[f[k]];y[k] += y[f[k]];
f[k] = rt;
return rt;
}
void merge(int a,int b,int dx,int dy)
{
int p = find(a),q = find(b);
if(p == q)return;
x[p] = dx + x[b] - x[a];
y[p] = dy + y[b] - y[a];
f[p] = q;
return;
}
int calc(int a,int b)
{
int p = find(a),q = find(b);
if(p != q)return -1;
return abs(x[a] - x[b]) + abs(y[a] - y[b]);
}
int main()
{
scanf("%d%d",&n,&m);
int a,b,d,w;
for(int i = 1;i <= m;++i)
{
a = read();b = read();
d = read();w = getc();
q[++tot] = (query){i,0,a,b,d,w,tot};
}
scanf("%d",&p);
for(int i = 1;i <= p;++i)
{
a = read();b = read();d = read();
q[++tot] = (query){d,1,a,b,0,0,tot};
}
for(int i = 1;i <= n;++i)f[i] = i;
sort(q + 1,q + 1 + tot,cmp);
for(int i = 1;i <= tot;++i)
{
if(q[i].type == 0)
{
if(q[i].f == 1)merge(q[i].a,q[i].b,0,q[i].d);
if(q[i].f == 2)merge(q[i].a,q[i].b,0,-q[i].d);
if(q[i].f == 3)merge(q[i].a,q[i].b,-q[i].d,0);
if(q[i].f == 4)merge(q[i].a,q[i].b,q[i].d,0);
}
else q[i].ans = calc(q[i].a,q[i].b);
}
sort(q + 1,q + 1 + tot,cmp_id);
for(int i = m + 1;i <= tot;++i)
{
printf("%d\n",q[i].ans);
}
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡