POJ 1703--Find them, Catch them
来源:互联网 发布:智多星定额造价软件 编辑:程序博客网 时间:2024/05/19 09:47
题意:一个城市有两个犯罪团伙,给定两种输入,第一种输入表示a,b两个人不在同一个团伙,第二种输入询问a,b是否是同一个团伙,输出到上一个输入为止能知道的他们的关系。
题解:并查集的一种扩展应用,原始的并查集集合中元素代表他们属于同一种集合,本题可以用这种集合代表有关系的一种集合,而集合类元素之间的关系则可以通过他们分别与根节点的关系求得。
- 关系转移:设IsSame[a] = 0代表a与他的根节点fa[a]属于同一团伙,等于1代表a与根节点不属于同一团伙,则若fa[a] == fa[b],a,b之间的关系:IsSame[a] ^ IsSame[b],同样为0代表a,b属于同一团伙,为1代表a,b属于不同团伙。
- 路径压缩:并查集的一种优化,在搜索a的根节点时直接将路径中的点指向最终的根节点,同样关系表IsSame[a]也需要随着根节点变化而变化。
注意:题意要求每个团伙至少有一个人,则当输入为两个人时,不需要任何其他输入我们就已经知道两个人属于不同团伙。而三个以上人,当没有关系提示时,我们不知道他们的关系,而当一有关系输入时,题设的条件已经能满足了。
#include<iostream>#include<cstdio>#include<cstring>using namespace std;class solve{private: int N,M; int* fa; int* height; char* IsSame; //1表示点与根节点不同伙,0表示同伙 char c; int a,b;public: solve(int n,int m):N(n),M(m) { fa = new int[N+1]; height = new int[N+1]; IsSame = new char[N+1]; makeSet(); if(n == 2) //每个犯罪团伙至少有一人 { unionSet(1,2); } while(M--) { getchar(); c = getchar(); scanf("%d%d",&a,&b); if(c == 'D') { unionSet(a,b); } else { if(findSet(a) == findSet(b)) { if(IsSame[a]^IsSame[b]) { printf("In different gangs.\n"); } else { printf("In the same gang.\n"); } } else { printf("Not sure yet.\n"); } } } return ; } ~solve() { delete[] fa; delete[] height; delete[] IsSame; } int makeSet(); int findSet(int x); int unionSet(int x,int y);};int solve::findSet(int x){ if(x == fa[x]) return x; int tmpfa = fa[x]; fa[x] = findSet(fa[x]); IsSame[x] ^= IsSame[tmpfa]; //关系表随着根节点变化而变化 return fa[x];}int solve::unionSet(int x,int y){ int rootX = findSet(x); int rootY = findSet(y); if(rootX != rootY) //根节点不同则开始合并 { if(height[rootX] > height[rootY]) //按树的深度大小进行合并 { fa[rootY] = rootX; IsSame[rootY] = IsSame[x]^IsSame[y]^1; //因为输入的x,y关系为1,经过x,y求得rootX和rootY的关系 } else { fa[rootX] = rootY; IsSame[rootX] = IsSame[x]^IsSame[y]^1; if(height[rootX] == height[rootY]) height[rootY]++; } } return 0;}int solve::makeSet(){ memset(IsSame,0,sizeof(char)*(N+1)); //初始化所有人与自己同伙 memset(height,0,sizeof(int)*(N+1)); for(int i = 1;i <= N;i++) { fa[i] = i; //初始化每个人和自己一组 } return 0;}int main(){ int T; int n,m; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); solve poj_1703(n,m); } return 0;}
0 0
- POJ 1703 Find them, Catch them
- poj 1703 Find them, Catch them
- POJ-1703 Find them, Catch them
- Poj 1703 Find them, Catch them
- poj 1703 Find them, Catch them
- POJ 1703 Find them, Catch them
- poj 1703 Find them, Catch them
- poj 1703 Find them, Catch them
- POJ 1703 - Find them, Catch them
- POJ 1703 Find them, Catch them
- POJ 1703(Find them, Catch them)
- POJ 1703 Find them, Catch them
- poj 1703 Find them, Catch them
- poj 1703 Find them, Catch them
- POJ 1703: Find them, Catch them
- poj 1703 find them,catch them
- POJ--1703--Find them, Catch them
- POJ 1703 Find them, Catch them
- 第十一周 项目二(3)单步调试 step into
- cmake将代码安装至其他目录
- ViewState(视图状态)持久性机制大全,页适配器
- 早到才是准时,准时就是迟到
- 洗牌算法
- POJ 1703--Find them, Catch them
- ZigZag Conversion ---leetcode
- 为什么现在的我们,连做一件小事都不能坚持?
- 第11周项目1-函数版型号图(2)
- 第十一周项目一 函数版星号图(2)
- 创建一个如下的窗体,并在窗体上放置saveFileDialog、openFileDialog两个控件。
- TabHost使用简介
- 女人们,这些技术男真的被“双十一”逼“疯”了!
- CI框架Session.php源码分析