BNU 51276 - 道路修建 Small (并查集)
2016-02-04 22:05
232 查看
题目链接:http://www.bnuoj.com/v3/problem_show.php?pid=51276
具体题意不描述了,一眼看过去就是并查集,关键是添加边以后更新答案。我是开个二维的数组ans记录答案,vector容器存储直接或间接相连的点(包括本身)。
代码如下:
具体题意不描述了,一眼看过去就是并查集,关键是添加边以后更新答案。我是开个二维的数组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); } } } }
相关文章推荐
- Codeforces Round #313 (Div. 2)--C. Gerald's Hexagon
- 23种设计模式(6):代理模式
- lct各类操作小记录
- UVALive 6436 The Busiest City
- 泛型和DAO设计
- 操作系统学习笔记:多媒体系统
- 自定义窗体(二)
- 操作系统学习笔记:多媒体系统
- 录制视频和播放视频的应用
- BFS
- 自定义窗体(一)
- 第十九课(二)
- 解决 Android Studio 乱码问题
- 《毛主席诗词全集》150首
- [转] 关于ubuntu的sources.list总结
- 使用STM32CUBEMX生成USB Mass Storage代码,通过SDIO读写TF卡
- GPS经纬度转换屏幕坐标
- 用树莓派搭建你自己的Web服务器,以及一个可以外网访问的Blog
- [转] 停止支持的老版本ubuntu源列表-old-releases
- jQuery性能优化