NYOJ 1022--合纵连横 【并查集删点】
2015-07-25 12:27
387 查看
合纵连横
时间限制:1000 ms | 内存限制:65535 KB难度:3
描述
乱世天下,诸侯割据。每个诸侯王都有一片自己的领土。但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土面积不断扩大。而实力弱的诸侯王为了不让自己的领土被吞并,他会联合一些其他同样弱小的诸侯国,组成联盟(联盟不止一个),来共同抵抗那些强大的诸侯国。 强大的诸侯国为了瓦解这些联盟,派出了最优秀的间谍来离间他们,使一些诸侯国退出联盟。最开始,每个诸侯国是一个联盟。
有两种操作
1、U x y 表示x和y在同一个联盟。(0≤x,y<n)
2、D x 表示x退出联盟。
输入多组测试数据
第一行两个数,n和m(1 ≤ n≤ 10^5, 1 ≤ m ≤10^5),分别表示诸侯国的个数和操作次数。
接下来有m行操作
输出输出联盟的个数
样例输入
5 7 U 0 1 U 1 2 U 0 3 D 0 U 1 4 D 2 U 0 2 10 1 U 0 9
样例输出
Case #1: 2 Case #2: 9
#include <cstdio> #include <cstring> #include <iostream> #define maxn 300000 using namespace std; int per[maxn * 4]; int vis[maxn * 4]; int ans, n, m; void init(){ ans = n + n; for(int i = 0; i < n; ++i) per[i] = i + n; for(int j = n; j <= n + n + m; j++) per[j] = j; memset(vis, 0 ,sizeof(vis)); } int find(int x){ if(x == per[x]) return x; return per[x] = find(per[x]); } void jion (int x, int y){ int fx = find(x); int fy = find(y); if(fx != fy) per[fx] = fy; } void del(int x){ per[x] = ans++; } void getmap(){ char str[10]; int a,b; while(m--){ scanf("%s", &str); if(str[0] == 'U'){ scanf("%d%d", &a, &b); jion(a, b); } else { scanf("%d", &a); del(a); } } } int main (){ int k = 1; while(scanf("%d%d", &n, &m)!=EOF){ init(); getmap(); int ans = 0; for(int i = 0; i < n ; ++i){ int x= find(i); if(!vis[x]){ ans++; vis[x] = 1; } } printf("Case #%d: %d\n", k++, ans); } return 0; }
相关文章推荐
- [算法]树的最大独立集(动态规划 dfs刷表)
- MSI安裝包如何在普通用戶權限下進行安裝程序
- PHP中exit()与die()的区别
- 获取手机的流量信息 /proc/pid/net/dev
- sgu299:Triangle(大水题)
- Linux命令总结
- Sqoop中文手册
- 有关yarn异常处理
- 恢复被文件夹病毒恶意隐藏的文件夹
- keepalived高可用反向代理的nginx
- System Generator学习笔记(五)
- android 第一课
- Spring MVC Restful构建中静态资源访问问题
- 上手iOS常见问题——iOS模拟器显示错位问题解决
- 四轴飞控
- Android Api Demos登顶之路(六)
- ubuntu 下输入法问题
- 有愿意共同发展USB固件做?
- Mac 下 docker安装
- [HDU 1664] Different Digits DFS+鸽巢原理