• HDU 2473 Junk-Mail Filter 删点并查集


    题目来源:HDU 2473 Junk-Mail Filter

    题意:2中操作 M x, y 将x,y 合并到一个集合 S x 将x从所在的集合去掉 自己成为一个集合 最后求有多少个集合

    思路:删点不好做 能够假设0 1 2在一个集合 能够定义个数组映射 就是每一个点所相应实际的点 開始是a[0] = 0 a[1] = 1 a[2] = 2

    如今要去掉2 能够定义一个新的点 原来的要删的点留着 原来a[2] = 2 a[2] = 3 如今的3就是原来的第二个2点 仅仅只是名字换成3了 a[2] = 3 以后訪问第二个点 都訪问a[2]

    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn = 1100010;
    int f[maxn], a[maxn], flag[maxn];
    int cnt;
    
    void init(int n)
    {
    	for(int i = 1; i <= n; i++)
    		f[i] = a[i] = i;
    	cnt = n;
    	memset(flag, 0, sizeof(flag));
    }
    
    int find(int x)
    {
    	if(x != f[x])
    		return f[x] = find(f[x]);
    	return f[x];
    }
    
    void merge(int x, int y)
    {
    	x = find(x);
    	y = find(y);
    	if(x != y)
    		f[x] = y;
    }
    void del(int x)
    {
    	find(a[x]);
    	f[++cnt] = cnt;
    	a[x] = cnt;
    }
    int main()
    {
    	int cas = 1;
    	int T;
    	int n, m;
    	while(scanf("%d %d", &n, &m) && (n||m))
    	{
    		init(n);
    		while(m--)
    		{
    			char s[10];
    			scanf("%s", s);
    			if(s[0] == 'S')
    			{
    				int x;
    				scanf("%d", &x);
    				x++;
    				del(x);
    			}
    			else
    			{
    				int x, y;
    				scanf("%d %d", &x, &y);
    				x++, y++;
    				merge(a[x], a[y]);
    			}
    		}
    		int ans = 0;
    		for(int i = 1; i <= n; i++)
    		{
    			int x = find(a[i]);
    			if(!flag[x])
    			{
    				ans++;
    				flag[x] = 1;
    			}
    		}
    		printf("Case #%d: %d
    ", cas++, ans);
    	}
    	return 0;
    }


  • 相关阅读:
    SiteMap Editor for Microsoft Dynamics CRM 2011 使用说明
    Microsoft Dynamics CRM 2011 如何导入组织
    SQL server 2008数据库的备份与还原(转)
    css列表
    css栅格
    css-排版
    类的操作
    事件的委派
    正则验证手机号和电子邮件
    div跟随鼠标移动
  • 原文地址:https://www.cnblogs.com/llguanli/p/6827935.html
Copyright © 2020-2023  润新知