您的位置:首页 > 其它

BNU 51276 - 道路修建 Small (并查集)

2016-02-04 22:05 232 查看
 题目链接:http://www.bnuoj.com/v3/problem_show.php?pid=51276

 具体题意不描述了,一眼看过去就是并查集,关键是添加边以后更新答案。我是开个二维的数组ans记录答案,vector容器存储直接或间接相连的点(包括本身)。

 代码如下:

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;
const int MAXN = 1005;
int par[MAXN] , ans[MAXN][MAXN];
vector<int> v[MAXN];

void init(int n) {  //初始化
for(int i = 1 ; i <= n ; i++) {
par[i] = i;
for(int j = i + 1 ; j <= n ; j++) {
ans[i][j] = ans[j][i] = 0;
}
v[i].clear();
v[i].push_back(i);   //清空后加入本身
}
}

int Find(int n) {
if(n == par
)
return n;
return par
= Find(par
);
}

int main()
{
int t , n , m , x , a , b , last , res;
scanf("%d" , &t);
while(t--) {
scanf("%d %d" , &n , &m);
init(n);
last = 0 , res = n;   //res为联通块数
for(int ca = 1 ; ca <= m ; ca++) {
scanf("%d %d %d" , &x , &a , &b);
a = a ^ last , b = b ^ last;
int aa = Find(a) , bb = Find(b);
if(x == 0) {
if(aa != bb) {     //不为同一个联通块
par[aa] = bb;
res--;
int xx = v[a].size() , yy = v[b].size();  //预先记录容器大小,不然下面的加点会使size增大
for(int i = 0 ; i < xx ; i++) {    //更新答案 加点
for(int j = 0 ; j < yy ; j++) {
ans[v[a][i]][v[b][j]] = ans[v[b][j]][v[a][i]] = ca;
v[v[a][i]].push_back(v[b][j]);
v[v[b][j]].push_back(v[a][i]);
}
}
}
last = res;
printf("%d\n" , last);
}
else {
last = ans[a][b];
printf("%d\n" , last);
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: