BZOJ 3362 POJ 1984 Navigation Nightmare 带权并查集
来源:互联网 发布:使命召唤ol自由数据 编辑:程序博客网 时间:2024/05/29 12:53
题目大意:一些农场由一些东西向或者南北向的路相互连接。在不断加边的过程中会询问两个农场的曼哈顿距离是多少,如果目前还不连通,那么输出-1。
思路:带权并查集,f[i]为点i到father[i]的距离,要维护两个值,一个是东西向的距离,一个是南北向的距离,因为以后更新的时候要用到。在合并的时候有些特殊。现在有一条边(x->y),设fx为x的根,fy为y的根,那么现在知道f到fx的距离,y到fy的距离,还知道x到y的距离,设fx到fy的距离为dis,则dis + f[y] = f[x] + edge[p].w,那么dis = f[x] - f[y] + edge[p].w。根据这个公式来合并两个树就可以了。
CODE:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 40010using namespace std;struct Complex{int x,y,len;char c;}edge[MAX];struct Ask{int x,y;int pos,_id;bool operator <(const Ask &a)const {return pos < a.pos;}}ask[MAX];struct Status{int x,y;Status(int _,int __):x(_),y(__) {}Status() {}Status operator +(const Status &a)const {return Status(x + a.x,y + a.y);}Status operator -(const Status &a)const {return Status(x - a.x,y - a.y);}}f[MAX];int points,edges,asks;int father[MAX];int ans[MAX];char s[10];void Pretreatment();int Find(int x);int main(){cin >> points >> edges;Pretreatment();for(int i = 1;i <= edges; ++i) {scanf("%d%d%d%s",&edge[i].x,&edge[i].y,&edge[i].len,s);edge[i].c = s[0];}cin >> asks;for(int i = 1;i <= asks; ++i)scanf("%d%d%d",&ask[i].x,&ask[i].y,&ask[i].pos),ask[i]._id = i;sort(ask + 1,ask + asks + 1);int now = 1;for(int i = 1;i <= edges; ++i) {int fx = Find(edge[i].x);int fy = Find(edge[i].y);if(fx != fy) {father[fy] = fx;Status temp;if(edge[i].c == 'N')temp = Status(0,edge[i].len);if(edge[i].c == 'S')temp = Status(0,-edge[i].len);if(edge[i].c == 'E')temp = Status(edge[i].len,0);if(edge[i].c == 'W')temp = Status(-edge[i].len,0);f[fy] = f[edge[i].x] - f[edge[i].y] + temp;}while(i >= ask[now].pos && now <= asks) {int fx = Find(ask[now].x);int fy = Find(ask[now].y);if(fx != fy)ans[ask[now]._id] = -1;else {Status temp = f[ask[now].x] - f[ask[now].y];ans[ask[now]._id] = abs(temp.x) + abs(temp.y);}++now;}}for(int i = 1;i <= asks; ++i)printf("%d\n",ans[i]);return 0;}void Pretreatment(){for(int i = 1;i <= points; ++i)father[i] = i;}int Find(int x){if(father[x] == x)return x;int temp = father[x];father[x] = Find(father[x]);f[x] = f[x] + f[temp];return father[x];}
0 0
- BZOJ 3362 POJ 1984 Navigation Nightmare 带权并查集
- BZOJ 3362 Navigation Nightmare 带权并查集
- poj 1984 Navigation Nightmare(带权并查集)
- 【POJ】1984 Navigation Nightmare 带权并查集
- POJ 1984 Navigation Nightmare 二维带权并查集
- POJ 1984 Navigation Nightmare (带权并查集)
- poj 1984 Navigation Nightmare(带权并查集)
- POJ 1984 Navigation Nightmare(带权并查集)
- POJ-1984-Navigation Nightmare [带权并查集]
- bzoj 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦 带权并查集
- 【POJ 1984】Navigation Nightmare (并查集)
- POJ--1984-Navigation Nightmare--并查集
- poj 1984 - Navigation Nightmare(并查集)
- POJ 1984 Navigation Nightmare 并查集
- poj1984 Navigation Nightmare(带权并查集)
- POJ 1984 Navigation Nightmare【并查集思路总结】
- POJ 1984 Navigation Nightmare(路径压缩并查集)
- POJ 1984 Navigation Nightmare (数据结构-并查集)
- CSS盒子模型
- HDU's ACM 1014 Uniform Generator
- Valid Number
- 【转】tomcat server.xml
- 由OpenSessionInViewFilter引起的No bean named 'sessionFactory' 异常
- BZOJ 3362 POJ 1984 Navigation Nightmare 带权并查集
- 《Systems Performance: Enterprise and the Cloud》读书笔记系列(六) —— 第二章(五)
- 有关Activity生命周期以及状态的保存操作的选择
- 第7周项目1-电阻串联
- dll方法调用引发的CrtIsValidHeapPointer错误
- How To Draw Graphs with Core Plot, Part 2
- QString的一些常用定义方法
- C#反射概念以及实例详解
- 实战:mysql版本升级