洛谷p1197[jsoi2008]星球大战

fastle      2022-02-10     584

关键词:

题目描述

很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。

但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通快的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。

输入输出格式

输入格式:

输入文件第一行包含两个整数,N (1 <= N <= 2M) 和M (1 <= M <= 200,000),分别表示星球的数目和以太隧道的数目。星球用0~N-1的整数编号。

接下来的M行,每行包括两个整数X, Y,其中(0<=X<>Y<N),表示星球X和星球Y之间有以太隧道。注意所有的以太隧道都是双向的。

接下来一行是一个整数K,表示帝国计划打击的星球个数。

接下来的K行每行一个整数X,满足0<=X<N,表示帝国计划打击的星球编号。帝国总是按输入的顺序依次摧毁星球的。

输出格式:

输出文件的第一行是开始时星球的连通块个数。

接下来的K行,每行一个整数,表示经过该次打击后现存星球的连通块个数。

***************************************************************

由于并查集难以进行删除的操作(要不怎么叫做并查集),我们便可以逆向思考一下,先求出所有星球都打击完之后

的连通块个数,然后一个个把打击的星球加上,同时再次统计连通块的个数。

以上是思想,但是在代码实现时,我认为有几点需要注意的(尤其是我这种==的代码)

1.对以太隧道进行储存时,可以借鉴图论中邻接表的方法,找出和一个点相连的所有隧道

2.统计连通块的个数可以用一个计数器,每次加入一个新点计数器自加,每次合并两个连通块计数器自减。

3.讲父节点初始值设为-1,加入这个节点时将其改为本身,这样比较好判断哪些点尚未加入

END

************************

#include<cstdio>
#include<algorithm>
#define maxn 200001
using namespace std;
struct Edge
{
    int num;
    int next;
}edge[maxn * 4];
int head[maxn * 2];
int note[maxn];
int shuru[maxn];
bool visited[maxn * 2];
int father[maxn * 2];
int top = 0;
int n,m,cns,k = 0;
int read()
{
    int num = 0;
    char c = getchar();
    int f = 1;
    while(c < '0'||c > '9')
    {
        if(c == '-')f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9')
    {
        num *= 10;
        num += c - '0';
        c = getchar();
    }
    return num * f;
}
int find(int x)
{
    return father[x] == x ? x:father[x] = find(father[x]);
}
void unionn(int vi,int vj)
{
    father[find(vj)] = find(vi);
}
void push(int vi,int vj)
{
    top ++;
    edge[top].num = vj;
    edge[top].next = head[vi];
    head[vi] = top;    
}
void Pang(int x)
{
    father[x] = x;    cns++;
    for(int i = head[x];i != -1;i = edge[i].next)
    {
        int j = edge[i].num;
        if(father[j] != -1)
        {
            if(find(j) != find(x))
            {
                unionn(x,j);
                cns--;
            }
        }
    }
}
int main()
{
    n = read();
    m = read();
    for(int i = 0;i < n;i ++)
    {
        father[i] = -1;
        head[i] = -1;
    }
    for(int i = 1;i <= m;i ++)
    {
        int vi = read(),vj = read();
        push(vi,vj);
        push(vj,vi);
    }
    k = read();
    for(int i = 1;i <= k;i ++)
    {
        shuru[i] = read();
        visited[shuru[i]] = true;
    }
    for(int i = 0;i < n;i ++)
    {
        if(!visited[i])
        {
            Pang(i);
        }
    }
    note[0]=cns;
    for(int i = k;i >= 1;i --)
    {
        Pang(shuru[i]);
        note[i] = cns;
    }
    for(int i = 1;i <= k;i ++)
    {
        printf("%d\n",note[i]);
    }
    printf("%d",note[0]);
    return 0;
}

 

洛谷p1197[jsoi2008]星球大战

题目描述很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互... 查看详情

洛谷p1197[jsoi2008]星球大战

题目描述很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互... 查看详情

洛谷p1197[jsoi2008]星球大战

题目描述很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互... 查看详情

p1197[jsoi2008]星球大战

P1197[JSOI2008]星球大战题目描述很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通... 查看详情

p1197[jsoi2008]星球大战

题目描述很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互... 查看详情

p1197[jsoi2008]星球大战

题目描述很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互... 查看详情

p1197[jsoi2008]星球大战并查集的逆向思维+链式前向星

P1197[JSOI2008]星球大战https://www.luogu.com.cn/problem/P1197我真的心态崩了,找了三个小时才发现错误在哪里。我的习惯是从1开始记录数据,一直就超时,怎么都超时,但还是能过几组样例,我以为是算法问题,没... 查看详情

p1197[jsoi2008]星球大战[删边求连通块个数](代码片段)

 展开题目描述很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以... 查看详情

luogup1197[jsoi2008]星球大战x

P1197[JSOI2008]星球大战题目描述很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通... 查看详情

[jsoi2008]星球大战starwar

1015:[JSOI2008]星球大战starwarTimeLimit:3Sec  MemoryLimit:162MBSubmit:6516  Solved:3024[Submit][Status][Discuss]Description  很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机... 查看详情

bzoj1015:[jsoi2008]星球大战starwar

二次联通门: BZOJ1015:[JSOI2008]星球大战starwar    /*BZOJ1015:[JSOI2008]星球大战starwar离线删点先建出删完点后的图然后一个一个往上加删掉的点*/#include<cstdio>#include<iostream>#defineMax400004#definergreg 查看详情

bzoj-1015:[jsoi2008]星球大战starwar(并查集)

1015:[JSOI2008]星球大战starwarTimeLimit: 3Sec  MemoryLimit: 162MBSubmit: 6784  Solved: 3180[Submit][Status][Discuss]Description  很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星 查看详情

[jsoi2008]星球大战starwar

TimeLimit:3Sec  MemoryLimit:162MBSubmit:6509  Solved:3019[Submit][Status][Discuss]Description  很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝... 查看详情

bzoj1015[jsoi2008]星球大战starwar

1015:[JSOI2008]星球大战starwar2017-09-02Description  很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的... 查看详情

[jsoi2008]星球大战

原题链接:https://www.luogu.org/problemnew/show/P1197题意简述:给出n个点的无向图,每次删去一个点,询问当前的连通块个数。删点太难做,不如加点,首先将询问读取,然后离线倒着处理。标记每个已经删去的点,首先计算出所有没... 查看详情

bzoj1015[jsoi2008]星球大战starwar

1015:[JSOI2008]星球大战starwarTimeLimit: 3Sec  MemoryLimit: 162MBSubmit: 5134  Solved: 2328[Submit][Status][Discuss]Description  很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星 查看详情

luogu_1197[jsoi2008]星球大战

#include<cstdio>#include<iostream>#include<vector>usingnamespacestd;constintN=400020;constintM=200010;intp[N],n,m,k,a[M],sum,ans[M];vector<int>G[N];boolb[N];intfind(intx){retur 查看详情

[jsoi2008]星球大战starwar

Description很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互... 查看详情