一开始我是不会写的,后来点开了题解:

无话可说……那就写吧……然而第一发跑成暴力分,后来加了一个优化:就是在询问里面提到过的边都不用再加了。

然后……然后就过了呀……

其实还有面向数据的编程的骚操作……既然卡过了那也没什么好说了。

以前的巨佬们Orz

Code:

#include <cstdio>
#include <cstring>
using namespace std; const int N = ;
const int M = 8e5 + ; int n, m, qn, tot = , head[N], ans = ;
int pCnt = , id[N], idCnt = , ufs[N], cnt[N][N];
bool ex[N][N], men[N][N], vis[N]; struct Edge {
int to, nxt;
} e[M]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} struct Pathway {
int u, v;
} path[M]; struct Query {
int type, u, v;
} q[M]; inline void read(int &X) {
X = ;
char ch = ;
int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void init() {
for(int i = ; i <= n; i++) ufs[i] = i;
} int find(int x) {
return x == ufs[x] ? x : ufs[x] = find(ufs[x]);
} inline void merge(int x, int y) {
int fx = find(x), fy = find(y);
if(ufs[fx] != fy) ufs[fx] = fy;
} void dfs(int x) {
vis[x] = ;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(!ex[x][y]) continue;
if(vis[y]) continue;
dfs(y);
}
} inline void reCnt() {
ans = ;
for(int i = ; i <= idCnt; i++) vis[i] = ;
for(int i = ; i <= idCnt; i++)
if(!vis[i]) {
ans++;
dfs(i);
}
} inline void addEdge(int p) {
int u = id[find(q[p].u)], v = id[find(q[p].v)];
cnt[u][v]++, cnt[v][u]++;
if(!ex[u][v]) {
ex[u][v] = ex[v][u] = ;
add(u, v), add(v, u);
} // reCnt();
} inline void delEdge(int p) {
int u = id[find(q[p].u)], v = id[find(q[p].v)];
cnt[u][v]--, cnt[v][u]--;
if(!cnt[u][v] && !cnt[v][u])
ex[u][v] = ex[v][u] = ; // reCnt();
} inline void query(int p) {
reCnt();
printf("%d\n", ans);
} int main() {
read(n), read(m);
for(int i = ; i <= m; i++)
read(path[i].u), read(path[i].v);
read(qn);
for(int i = ; i <= qn; i++) {
char op[];
scanf("%s", op);
if(op[] == 'l') {
q[i].type = , read(q[i].u), read(q[i].v);
men[q[i].u][q[i].v] = men[q[i].v][q[i].u] = ;
}
if(op[] == 'c') {
q[i].type = ;
read(q[i].u), read(q[i].v);
men[q[i].u][q[i].v] = men[q[i].v][q[i].u] = ;
}
if(op[] == 'q') q[i].type = ;
} init();
for(int i = ; i <= m; i++) {
if(men[path[i].u][path[i].v]) continue;
merge(path[i].u, path[i].v);
}
for(int i = ; i <= n; i++) {
int nowf = find(i);
if(!vis[nowf]) vis[nowf] = , id[nowf] = ++idCnt;
} /* for(int i = 1; i <= n; i++)
printf("%d ", id[find(i)]);
printf("\n"); */ for(int i = ; i <= m; i++) {
if(!men[path[i].u][path[i].v]) continue;
int x = id[find(path[i].u)], y = id[find(path[i].v)];
add(x, y), add(y, x);
ex[x][y] = ex[y][x] = ;
cnt[x][y]++, cnt[y][x]++;
} // reCnt();
for(int i = ; i <= qn; i++) {
if(q[i].type == ) addEdge(i);
if(q[i].type == ) delEdge(i);
if(q[i].type == ) query(i);
} return ;
}

WOJ 18 动态无向图的更多相关文章

  1. 【转】Android IDA 动态调试最完善攻略,跨过各种坑

    前提条件和运行环境一定要写清楚,不然会有很多坑,坑死人. (1)IDA 是最新的7.0版本  (2) JDB 使用Java安装目录下的 (3)系统是win10 使用命令窗口时有很大的差别 (4)手机是 ...

  2. Python如何动态的为对象添加方法或属性,__slots__用法

    代码示例如下: import types    #使用MethodType方法需要导入包 class test(object):  #定义 一个test类,包含name属性和f()方法 def __i ...

  3. python 函数之day3

    一 函数的语法及特性 什么是函数? 定义:函数是一个功能通过一组语句的集合,由名字(函数名)将其封装起来的代码块,要想执行这个函数,只要调用其函数名即可. 特性: 减少重复代码 使程序变的可扩展 使程 ...

  4. winserver2008 DNS 很详细

    from http://www.it165.net/admin/html/201312/2182.html DNS(Domain Name System域名系统)区域化管理 分布式 层次性 域名空间结 ...

  5. 《构建高性能web站点》随笔 无处不在的性能问题

    前言– 追寻大牛的足迹,无处不在的“性能”问题. 最近在读郭欣大牛的<构建高性能Web站点>,读完收益颇多.作者从HTTP.多级缓存.服务器并发策略.数据库.负载均衡.分布式文件系统多个方 ...

  6. asp.net(C#)页面事件顺序

    asp.net(C#)页面事件顺序 http://www.cnblogs.com/henw/archive/2012/02/09/2343994.html   1 using System.Data; ...

  7. 第九章:四大组件之Broadcast Receiver

    第九章:四大组件之Broadcast Receiver   一.广播的功能和特征 广播的生命周期很短,经过调用对象-->实现onReceive-->结束,整个过程就结束了.从实现的复杂度和 ...

  8. spring ioc 原理 spring aop原理

    大家一直都说spring的IOC如何如何的强大,其实我倒觉得不是IOC如何的强大,说白了IOC其实也非常的简单.我们先从IOC说起,这个概念其实是从我们平常new一个对象的对立面来说的,我们平常使用对 ...

  9. Objective-c知识小结

    1.创建一个类产生.h和.m两个文件,.h中对用到的变量.方法作声明,.m文件中实现,导入时只导入.h文件,如果直接把方法写在.m文件中,未在.h文件中进行声明,则是私有方法  2.@interfac ...

随机推荐

  1. stl_algobase.h

    stl_algobase.h // Filename: stl_algobase.h // Comment By: 凝霜 // E-mail: mdl2009@vip.qq.com // Blog: ...

  2. nodepad++的python环境变量设置

    转:http://blog.csdn.net/memray/article/details/42041975

  3. getParameter() getInputStream()和getReader() 区别

    我们经常用servlet和jsp, 经常用request.getParameter() 来得到数据. request.getParameter() request.getInputStream() r ...

  4. HIVE-默认分隔符的(linux系统的特殊字符)查看,输入和修改

    这段时间做hive的时候,用到了系统默认分隔符.通常下面2中情况我们需要需要用到分隔符 1,制作table的输入文件,有时候我们需要输入一些特殊的分隔符 2,把hive表格导出到本地时,系统默认的分隔 ...

  5. Cloudera API访问

    多租户管理页面(admin)操作 cloudera 管理页面页面操作多租户是这样的: 进入到YARN的服务页面,点击Resource Pool,你将会看到已经存在的资源池,然后再点击资源池表格右上角的 ...

  6. 异常java.sql.SQLException: Field 'id' doesn't have a default value

    使用spring data jpa出现这个情况. entity中的自增策略已经加好了. 还是出现这个异常.去数据库中查看,发现没有给主键加上自增. 出现这个问题去实体类跟数据库中看一下就可以了.

  7. SVN 命令使用-***

    1.检出到某一版本: svn checkout -r 974  svn://220.231.xx.xx/仓库名 svn checkout  svn://220.231.xx.xx/仓库名 svn ex ...

  8. JSF页面中的JS取得受管bean的数据(受管bean发送数据到页面)

    JSF中引入jsf.js文件之后,可以拦截jsf.ajax.request请求.一直希望有一种方法可以像jquery的ajax一样,能在js中异步取得服务器端发送的数据.无奈标准JSF并没有提供这样的 ...

  9. 备份Ubuntu系统

    1.工具:再生龙 2.备份方法:使用再生龙将系统备份(在U盘/boot目录下有很多文件),可以通过这个U盘去装机.将这个U盘生成的文件发送给应用,应用会将其打包生成iso可发布版本: 3.操作步骤:

  10. uboot指令和环境变量

    一.uboot指令 1.printenv(pri) - 打印环境变量 2.setenv - 设置环境变量,和saveenv 配合使用 3.saveenv - 保存环境变量 4.run - 执行设置好的 ...