卧薪尝胆,厚积薄发。
      
    
            USACO2004FEB Navigation Nightmare 导航噩梦
        
        
        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;
}
 In tag:
数据结构-并查集
          In tag:
数据结构-并查集 
          
        
        Copyright © 2020
        
          wjh15101051
        
      
      ღゝ◡╹)ノ♡
     Date: Sun Oct 21 11:11:01 CST 2018
          Date: Sun Oct 21 11:11:01 CST 2018
           In Category:
          In Category:
           
         Timeline
            Timeline
           About
            About
           Toolbox
            Toolbox
           Friends
              Friends