zoukankan      html  css  js  c++  java
  • 洛谷 P1197 [JSOI2008]星球大战

    题意简述

    有n个点和m条通道,
    现在按顺序破坏k个点
    求每一次破坏后联通块的个数

    题解思路

    并查集,逆序做,
    先假设给的k个星球全都被炸,求出此时的联通块个数,就是经过k次打击的联通块个数。
    然后每次加上一个被炸的星球,就求出了经过每次次打击后的联通块个数

    代码

    #include <cstdio>
    using namespace std;
    int n, m, k, u, v, cnt, sum, x, y;
    int d[401000], fa[401000], ans[401000];
    int f[401000], to[801000], nxt[801000];
    bool bd[401000];
    void add_edge(int u, int v)
    {
    	to[++cnt] = v;
    	nxt[cnt] = f[u];
    	f[u] = cnt;
    }
    int gf(int x)
    {
    	return x == fa[x] ? x : fa[x] = gf(fa[x]);
    }
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for (register int i = 1; i <= m; ++i)
    	{
    		scanf("%d%d", &u, &v);
    		add_edge(u, v);
    		add_edge(v, u);
    	}
    	for (register int i = 0; i < n; ++i) fa[i] = i;
    	scanf("%d", &k);
    	for (register int i = 1; i <= k; ++i)
    	{
    		scanf("%d", &d[i]);
    		bd[d[i]] = 1;
    	}
    	sum = n - k;
    	for (register int i = 0; i < n; ++i)
    		if (!bd[i])
    			for (register int j = f[i]; j; j = nxt[j])
    				if (!bd[to[j]])
    				{
    					x = gf(i);
    					y = gf(to[j]);
    					if (x != y)
    					{
    						fa[y] = x;
    						--sum;
    					}
    				}
    	ans[k + 1] = sum;
    	for (register int i = k; i; --i)
    	{
    		++sum;
    		bd[d[i]] = 0;
    		x = gf(d[i]);
    		for (register int j = f[d[i]]; j; j = nxt[j])
    			if (!bd[to[j]])
    			{
    				y = gf(to[j]);
    				if (x != y)
    				{
    					fa[y] = x;
    					--sum;
    				}
    			}
    		ans[i] = sum;
    	}
    	for (register int i = 1; i <= k + 1; ++i) printf("%d
    ", ans[i]);
    }
    
  • 相关阅读:
    Nodejs-内置核心模块&npm包管理工具

    python 内置函数
    序列化和反序列化(json 和pickle)dumps 为序列化, json为反序列化
    迭代器iter()
    生成器 yield
    装饰器的解释说明
    面向过程中的局部变量(global)
    函数的参数设定
    集合的基本操作
  • 原文地址:https://www.cnblogs.com/xuyixuan/p/9594419.html
Copyright © 2011-2022 走看看