// 此博文为迁移而来,写于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. SpringBoot 系列教程自动配置选择生效

    191214-SpringBoot 系列教程自动配置选择生效 写了这么久的 Spring 系列博文,发现了一个问题,之前所有的文章都是围绕的让一个东西生效:那么有没有反其道而行之的呢? 我们知道可以通 ...

  2. nginx location笔记

    nginx location笔记= 开头表示精确匹配^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可.nginx不对url做编码,因此请求为/static/20%/aa,可以被规则 ...

  3. Kubernetes ingress 上传文件大小限制

    1.文件太大 413:Request Entity Too Large 创建 ingress 时添加 annotations(注释) metadata: annotations: nginx.ingr ...

  4. golang语言特性

    1. 垃圾回收 a. 内存⾃动回收,再也不需要开发⼈员管理内存 b. 开发人员专注业务实现,降低了心智负担 c. 只需要new分配内存,不需要释放   2. 天然并发 a. 从语⾔层面⽀持并发,⾮常简 ...

  5. Redis学习之zskiplist跳跃表源码分析

    跳跃表的定义 跳跃表是一种有序数据结构,它通过在每个结点中维持多个指向其他结点的指针,从而达到快速访问其他结点的目的 跳跃表的结构 关于跳跃表的学习请参考:https://www.jianshu.co ...

  6. Guarded Suspension设计模式

    Guarded Suspension 设计模式可以保证,当线程在访问某个对象时,发现条件不满足,就挂起等待条件满足时再次访问 public class GuardedSuspensionQueue { ...

  7. [转] console.log的高级用法

    //基本用法 console.log('最常见用法\n换行'); console.error('输出错误信息 会以红色显示'); console.warn('打印警告信息 会以黄色显示'); cons ...

  8. 好久没写原生的PHP调用数据库代码了分享个

    好久没写原生的PHP代码调用数据库了 eader("Content-type: text/html; charset=utf-8"); $time=$symptoms=$attr= ...

  9. asp.net SQLite关于各版本的调试

    最近想做一个简版的管理系统,将SQL SERVER数据库切换到SQLite数据库中,采用的是SQLite3的版本数据库. 开发工具:SV2015 UP3 数据库:SQLite3 项目整体结构图 相同的 ...

  10. 我是如何一步步编码完成万仓网ERP系统的(十一)产品库设计 7.发布商品

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...