Corporative Network UVA - 1329(并查集的修改与查询)
2017-08-18 17:01
489 查看
题目链接:https://vjudge.net/problem/UVA-1329
题目描述:给定n个点,一开始其父节点都是其自身。两个直接相连的结点uv间的距离是abs(u - v) % 1000。进行两种操作,E i 代表查询i到其父节点的距离,I i j表示将i的前驱结点设为j(i j直接相连)。其实也就是修改了一些父节点的值,求某个结点到根节点的距离。在贴场上写的AC代码前突然想到一组样例自己的代码不知道能不能过,一试果然不能通过,可是还是AC了,可能测试数据太水了吧。场上写的是很普遍的并查集写法,只是在Find(x)回溯时求出当前节点到其根节点的距离。虽然能AC可是过不了自己出的一组样例。换了一种写法,不再记录每个点到其根节点的距离,而是在E
i 时直接通过不停沿着父节点找到根节点,在找的过程中计算距离,这种方法可以过所有的样例,场上怕超时没那样写。下面附上两种代码,代码最后附上卡住自己的样例。不知道真的是数据太水还是我自己理解有误,欢迎大家指正或赐教。
代码如下:
场上AC但是过不了自己出的样例的代码:
题目描述:给定n个点,一开始其父节点都是其自身。两个直接相连的结点uv间的距离是abs(u - v) % 1000。进行两种操作,E i 代表查询i到其父节点的距离,I i j表示将i的前驱结点设为j(i j直接相连)。其实也就是修改了一些父节点的值,求某个结点到根节点的距离。在贴场上写的AC代码前突然想到一组样例自己的代码不知道能不能过,一试果然不能通过,可是还是AC了,可能测试数据太水了吧。场上写的是很普遍的并查集写法,只是在Find(x)回溯时求出当前节点到其根节点的距离。虽然能AC可是过不了自己出的一组样例。换了一种写法,不再记录每个点到其根节点的距离,而是在E
i 时直接通过不停沿着父节点找到根节点,在找的过程中计算距离,这种方法可以过所有的样例,场上怕超时没那样写。下面附上两种代码,代码最后附上卡住自己的样例。不知道真的是数据太水还是我自己理解有误,欢迎大家指正或赐教。
代码如下:
场上AC但是过不了自己出的样例的代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<cstdlib> #include<sstream> #include<deque> #include<stack> #include<set> #include<map> using namespace std; typedef long long ll; typedef unsigned long long ull; const double eps = 1e-6; const int maxn = 20000 + 10; const int maxt = 300 + 10; const int mod = 10; const int dx[] = {1, -1, 0, 0}; const int dy[] = {0, 0, -1, 1}; const int Dis[] = {-1, 1, -5, 5}; const int inf = 0x3f3f3f3f; const int MOD = 1000; int n, m, k; int dis[maxn][maxn], fa[maxn]; int Find(int x){ if(x == fa[x]) return x; int y = Find(fa[x]); dis[x][y] = dis[x][fa[x]] + dis[fa[x]][y];//回溯前记录当前节点到其根节点的距离=当前节点到其父节点距离+其父节点到根节点的距离 return fa[x] = y;//修改根节点 } int main(){ int t; scanf("%d", &t); while(t--){ scanf("%d", &n); memset(dis, 0, sizeof dis); getchar(); for(int i = 0; i < maxn; ++i) fa[i] = i; char ch[5]; int x, y, xx, yy; while(scanf("%s", &ch) == 1){ if(ch[0] == 'O') break; if(ch[0] == 'E'){ scanf("%d", &x); y = Find(x); printf("%d\n", dis[x][y]); continue;//输出x到其根节点y的距离 } if(ch[0] == 'I'){ scanf("%d%d", &x, &y);//y是x的父节点 if(x == y){ dis[x][y] = 0; fa[x] = x; continue; } yy = Find(y);//找到新的根节点 fa[x] = yy; dis[x][yy] = dis[y][yy] + (abs(x - y) % MOD);} } } return 0; } /* 此代码无法通过该组样例: 1 6 E 3 I 3 1 E 3 I 1 2 E 3 I 2 4 E 1 E 3 I 2 5 I 5 6 E 2 E 1 E 3 O */记录父节点,在查询时现求当前节点到根节点的距离的代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<cstdlib> #include<sstream> #include<deque> #include<stack> #include<set> #include<map> using namespace std; typedef long long ll; typedef unsigned long long ull; const double eps = 1e-6; const int maxn = 20000 + 10; const int maxt = 300 + 10; const int mod = 10; const int dx[] = {1, -1, 0, 0}; const int dy[] = {0, 0, -1, 1}; const int Dis[] = {-1, 1, -5, 5}; const int inf = 0x3f3f3f3f; const int MOD = 1000; int n, m, k; int dis[maxn][maxn], fa[maxn]; int Find(int x){//返回x到其当前根节点的距离 if(x == fa[x]) return 0; int num = 0; while(x != fa[x]){//从前驱节点一直向前求距离直至求到根节点 num += abs(fa[x] - x) % MOD; x = fa[x]; } return num; } int main(){ int t; scanf("%d", &t); while(t--){ scanf("%d", &n); memset(dis, 0, sizeof dis); for(int i = 0; i < maxn; ++i) fa[i] = i; char ch[5]; int x, y; while(scanf("%s", ch) == 1){ if(ch[0] == 'O') break; if(ch[0] == 'E'){ scanf("%d", &x); printf("%d\n", Find(x)); continue; } if(ch[0] == 'I'){ scanf("%d%d", &x, &y); fa[x] = y;//将x的前驱节点(父节点)设为y } } } return 0; } /* 此代码可以通过该组样例: 1 6 E 3 I 3 1 E 3 I 1 2 E 3 I 2 4 E 1 E 3 I 2 5 I 5 6 E 2 E 1 E 3 O */
相关文章推荐
- Corporative Network UVA - 1329 加权并查集(压缩路径优化)
- C - Corporative Network UVA - 1329 (并查集)
- C - Corporative Network UVA - 1329 -加权并查集
- Corporative Network UVA - 1329 加权并查集
- UVA 1329 Corporative Network
- UVALive 3027---Corporative Network+并查集的应用
- Corporative Network +uvalive+并查集
- UVA 1329 - Corporative Network
- Corporative Network UVALive - 3027 并查集
- Corporative Network UVA - 1329
- uvalive 4730(并查集+区间修改单点查询)
- UVA 1329 Corporative Network(并查集)
- Uva 10596 - Morning Walk 欧拉回路基础水题 并查集实现【uva数据修改,代码已更新】
- UVA 1329 Corporative Network(并查集:路径压缩)
- LA 3027 Corporative Network / 并查集
- UVA-1329 - Corporative Network(并查集)
- UVA 11987 Almost Union-Find (单点修改的并查集)
- UVALive 4730 Kingdom(线段树区间修改+并查集)
- UVA 11987 Almost Union-Find 并查集单点修改
- Corporative Network UVA - 1329 加权并查集