• FZU 2155 盟国


     Problem 2155 盟国


     Problem Description

    世界上存在着N个国家,简单起见,编号从0~N-1,假如a国和b国是盟国,b国和c国是盟国,那么a国和c国也是盟国。另外每一个国家都有权宣布退盟(注意,退盟后还能够再结盟)。

    定义以下两个操作:

    “M X Y” :X国和Y国结盟

    “S X” :X国宣布退盟

     Input

    多组case。

    每组case输入一个N和M (1 ≤ N ≤ 100000 , 1 ≤ M ≤ 1000000),N是国家数。M是操作数。

    接下来输入M行操作

    当N=0,M=0时,结束输入

     Output

    对每组case输出终于有多少个联盟,格式见例子。

     Sample Input

    5 6
    M 0 1
    M 1 2
    M 1 3
    S 1
    M 1 2
    S 3
    3 1
    M 1 2
    0 0

     Sample Output

    Case #1: 3
    Case #2: 2

    代码:
    /**
    *  解题思路: 含删除的并查集题。用一个real[]数组标记每一个点的真实位置。
    *  目的是删除一个点后,将他的位置移到原总数组的末尾,
    *  这样原来的数组也不会被破坏。
    */
    #include <stdio.h>
    #include <string.h>
    #define MAX 500005
    int father[MAX];
    int real[MAX];
    int vis[MAX];
    int n, m, all;
    int find(int x) 
    {
    	if (father[x] == x)
    		return x;
    	else
    		return (father[x] = find(father[x]));
    }
    void merge(int a, int b)
    {
    	int x, y;
    	x = find(a);
    	y = find(b);
    	if (x != y)
    		father[x] = y;
    }
    int main()
    {
    	int t = 1;
    	while (scanf("%d%d", &n, &m) != EOF)
    	{
    		if (0 == n && 0 == m)
    			return 0;
    		char op;
    		all = n;
    		memset(vis, 0, sizeof(vis));
    		for (int i = 0; i < n; i++){
    			father[i] = i;
    			real[i] = i;
    		}
    		for (int i = 0; i < m; i++)
    		{
    			getchar();
    			scanf("%c", &op);
    			if ('M' == op){
    				int a, b;
    				scanf("%d%d", &a, &b);
    				merge(real[a], real[b]);  //将真实位置相连
    			}
    			else
    			{
    				int x;
    				scanf("%d", &x);
    				father[all] = all;  
    				real[x] = all++;  // 删除x点。就把x的真实位置放到原数组末尾。
    			}
    		}
    		int ans = 0;
    		for (int i = 0; i < n; i++)
    		{
    			int u = find(real[i]);
    			if (0 == vis[u]){
    				vis[u] = 1;
    				ans++;
    			}
    		}
    		printf("Case #%d: %d
    ", t++, ans);
    	}
    	return 0;
    }
  • 相关阅读:
    PSP编程
    题库软件1.0发布
    ubuntu上安装netgear wg511v2驱动
    boost的编译
    Plot3D 0.3发布
    立体画板Plot3D
    求教团队内的朋友,在directx中,如何画虚线?
    OpenGL如何显示文本?
    JZ028数组中出现次数超过一半的数字
    JZ027字符串的排列
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6855965.html
Copyright © 2020-2023  润新知