// 此博文为迁移而来,写于2015年7月16日,不代表本人现在的观点与看法。原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6le.html

1、题目

【P.S. BZOJ上的题面问题很多,这里进行了一些修改和简化】

 
2、TAG

JSOI2008江苏省队选拔题;并查集。

3、分析
       作为一道省队选拔题确实感觉有点水水的。可能唯一难点在于难以想到这种方式。由题意,我们先可以想出一种最暴力的做法——对于每次的摧毁,跑一遍DFS判断连通块个数。然而这速度也是极慢的。
       可以这样想:一个星球与其他若干星球相连,则它们必定属于一个连通块;如果将其摧毁,即相当于将所有与其相连的星球拆开,不再属于同一个连通块。但是这样的话,我们难以判断某两个星球它们是不是存在除经过该星球的其他连通路径。
       所以我们可以反过来思考——首先我们将所有要摧毁的星球摧毁,计算出最后时刻的连通块个数,然后我们根据题目所给顺序反着对其进行加点,每一次的添加星球,都是将所有与其相连的星球并入同一个连通块。这样,我们就不需要考虑他们之前的状态了。并入的过程用并查集完成即可。
        
4、代码
---------------------------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#define MAXN 400005

struct Edge
{
        int v,next,flag;
};
Edge edge[MAXN];

int vis[MAXN],now=1,h[MAXN],n,m,v,u,p[MAXN],k,tot,set[MAXN],ans[MAXN],flag[MAXN],del[MAXN];

void addEdge(int u,int v)
{
        now++;
        edge[now].v=v;
        edge[now].next=h[u];
        h[u]=now;
}

int check(int x)
{
        if (set[x]==x) return x;
        return (set[x]=check(set[x]));
}

void DFS(int now,int nowFa)
{
        for (int x=h[now];x!=-1;x=edge[x].next) 
         if (!vis[edge[x].v]) { vis[edge[x].v]=1; set[check(now)]=check(edge[x].v); DFS(edge[x].v,nowFa); }
        return;
}

void init()
{
        memset(h,-1,sizeof(h));
        scanf("%d %d",&n,&m);
        for (int i=1;i<=m;i++) 
        {
                scanf("%d %d",&u,&v);
                addEdge(u,v),addEdge(v,u);
        }
        scanf("%d",&k);
        for (int i=1;i<=k;i++) 
        {
                scanf("%d",&p[i]);
                vis[p[i]]=1;
                del[p[i]]=1;
        }
        for (int i=0;i<=n-1;i++) set[i]=i;
        for (int i=0;i<=n-1;i++) if (!vis[i]) { DFS(i,i); tot++; }
}

int main()
{
        init();
        int temp=tot;
        for (int i=k;i>=1;i--)
        {
                del[p[i]]=0; tot++;
                for (int x=h[p[i]];x!=-1;x=edge[x].next)
                {   
                        if (del[edge[x].v]) continue;
                        int v1=check(p[i]),v2=check(edge[x].v);
                        if (v1!=v2) { set[v1]=v2; tot--; }
                }
                ans[i]=tot;
        }
        for (int i=1;i<=k;i++) printf("%d\n",ans[i]);
        printf("%d",tot);
        return 0;
}
---------------------------------------------------------------------------------------------------

[BZOJ1015/JSOI2008]星球大战的更多相关文章

  1. BZOJ1015[JSOI2008]星球大战starwar[并查集]

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 5253  Solved: 2395[Submit ...

  2. BZOJ1015 [JSOI2008]星球大战starwar(并查集)

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 3895  Solved: 1750[Submit ...

  3. [Bzoj1015][JSOI2008]星球大战starwar(并查集)(离线处理)

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 6849  Solved: 3204[Submit ...

  4. BZOJ1015 [JSOI2008]星球大战starwar

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

  5. [洛谷P1197/BZOJ1015][JSOI2008]星球大战Starwar - 并查集,离线,联通块

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

  6. 2018.09.26 bzoj1015: [JSOI2008]星球大战starwar(并查集)

    传送门 并查集经典题目. 传统题都是把删边变成倒着加边,这道题是需要倒着加点. 处理方法是将每个点与其他点的边用一个vector存起来,加点时用并查集统计答案就行了. 代码: #include< ...

  7. [bzoj1015](JSOI2008)星球大战 starwar(离线+并查集)

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

  8. BZOJ1015: [JSOI2008]星球大战starwar【并查集】【傻逼题】

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

  9. bzoj1015: [JSOI2008]星球大战starwar 并查集+离线处理

    题目传送门 这道题可以改为离线处理 倒着找答案 这样删点就变成加点了 有了这个思想题目就很好写了哇 23333 #include<cstdio> #include<cstring&g ...

随机推荐

  1. 使用GitHub的仓库以及介绍

    一.创建仓库 假如Responsitory name是Hello-World Description一栏中可以设置仓库的说明. Public, Private  在这一栏可以选择Public还是Pri ...

  2. centos下java环境搭建安装

    1. 购买服务器(阿里云) 2. 重置密码,重启服务器 3. 创建账号work groupadd work #创建组 mkdir /data # 创建数据文件夹 useradd -d /data/wo ...

  3. | C语言I作业12

    C语言I作业12-学期总结 标签:18软件 李煦亮 问题 答案 这个作业属于那个课程 C语言程序设计I 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/S ...

  4. 移动端布局方案—vw+rem

    前言 首先你要知道 vw 和 rem 是什么?怎么使用? ①:简单来说 vw 是视口单位,相当于把视口等分成了100,1vw = 1; ②:rem是相对单位,设置根元素 html 的 font-siz ...

  5. office常用技巧汇总

    1.excel篇 (1)一次选择多行 可以利用SHIFT+鼠标实现,点第一行,按下鼠标,点200行,就能实现1~200行选择了. 总结:就是一直按住shift键,鼠标点击要选择的首行,再点击尾行.

  6. Appium+python自动化(一)- 环境搭建—上(超详解)

    简介 今天是高考各地由于降水,特别糟糕,各位考生高考加油,全国人民端午节快乐.最近整理了一下自动化的东西,先前整理的python接口自动化已经接近尾声.即将要开启新的征程和篇章(Appium& ...

  7. Web应急:网站被植入Webshell

    网站被植入webshell,意味着网站存在可利用的高危漏洞,攻击者通过利用漏洞入侵网站,写入webshell接管网站的控制权.为了得到权限 ,常规的手段如:前后台任意文件上传,远程命令执行,Sql注入 ...

  8. 2019-11-29-VisualStudio-使用三个方法启动最新-C#-功能

    原文:2019-11-29-VisualStudio-使用三个方法启动最新-C#-功能 title author date CreateTime categories VisualStudio 使用三 ...

  9. 外网IP和内网IP区别

    外网IP和内网IP区别? 网络结构 如图,假设我们的计算机现在就是设备一,我们想要访问百度.如果我们正使用着校园网,那么首先我们需要先通过校园网的路由器把我们的内网ip转为校园网的外网ip.然后通过这 ...

  10. WebAPI HelpPage帮助页

    WebAPI HelpPage是个插件,根据代码的注释生成API说明页,一目了然. 下面开始安装和配置 1.添加引用 先选择管理NuGet程序包,搜索 Microsoft.AspNet.WebApi. ...