// 此博文为迁移而来,写于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. Django学习——全局templates引用的问题

    一.问题在构建网站的时候我们会用到全局的templates处理错误的网页,此时我们需要对urls进行一个映射,使得在使用的时候避免重复调用.在使用的时候还会产生错误代码:第一个是404界面的,第二个是 ...

  2. win10系统优化

    1.服务:关闭 windows update\ windows search \ windows 备份 2.系统:高级系统设置->性能最优,同事修改虚拟内存如下 3.任务管理器:关闭多余的启动项 ...

  3. 【spring boot】spring boot 基于redis pipeline 管道,批量操作redis命令

    spring boot 2.x 使用RedisTemplate 操作 =================================== 1.pom.xml <!--spring2.0集成r ...

  4. 有关Oracle 查询时间的记录 (1)

    目录 写在前面 一.年.月.日.季.周 二.EXTRACT 年.月.日 三.上个星期一到星期天 四.1分钟前.1小时前.1月前.1年前 五.当月.上月.当天.前天 写在前面 在使用Oracle数据开发 ...

  5. winform按钮美化(非图片)

    在开发过程中,突然发现vs自带的按钮属性中通过修改Button控件的BackColor的颜色和字体颜色(ForeColor属性)及大小,如下图 就能达到简单美化按钮的效果,下面是显示效果 有兴趣的同学 ...

  6. 记录一次OracleJDK开发的项目发部到Linux中使用OpenJDK启动后失败的错误的解决方案

    一.现象 基于JAVA SpringBoot2.0.4的项目,发部后项目发部后,放到OpenJDK环境中运行时,提示下列错误: 2019-10-22 10:03:55 [main] WARN  o.s ...

  7. 图层树右键菜单结合Command操作过程

         图层树右键菜单结合Command操作过程 根据老师线上培训图层树右键菜单的生成,添加contextMenuStrip后再依次添加.命名ToolStripMenuItem,若将全部‘项’添加C ...

  8. 用Python分析国庆旅游景点,告诉你哪些地方好玩、便宜、人又少

    注:本人参考“裸睡的猪”公众号同名文章,学习使用. 一.目标 使用Python分析出国庆哪些旅游景点:好玩.便宜.人还少的地方,不然拍照都要抢着拍! 二.获取数据 爬取出行网站的旅游景点售票数据,反映 ...

  9. 基于vue+springboot+docker网站搭建【三】安装docker

    安装docker 我们整个工程都会基于docker来跑,因此首先安装docker.在安装所有软件之前,我们需要先下载一个下载工具. 1.下载工具安装  yum-utils yum install -y ...

  10. token安全之任意密码重置

    前言 偶然间挖了一个漏洞是密码重置,挖掘过程很有趣,可以参考下. 挖掘过程 在说明之前我们可以先走下正常流程,这样才方便查漏~ 正常流程 第一步骤: 正常填写完,点击下一步发送请求: POST /[U ...