【NOIP模拟题】连通
2016-01-29 10:57
351 查看
Overview
给定一个无向图,请编写一个程序实现以下两种操作:(1)D x y,从原图中删除连接x和y顶点的边。
(2)Q x y,询问x和y顶点是否连通。
Analysis
这也是连通问题,考虑用并查集解决。但是这是删除的问题耶,怎么办?
考虑将删除变为连通,能不能将所有操作给反过来,从最后一个操作开始处理。
当然是可以的。
Code
#include <bits/stdc++.h> using namespace std; typedef long long Lint; const int N=161240*4; const int MOD=100009; int n,q; int f ; char kind ; int cx ,cy ; inline int read(void) { int s=0; char c=getchar(); for (;!isdigit(c);c=getchar()); for (;isdigit(c);c=getchar()) s=s*10+c-'0'; return s; } int m; int ed [2]; struct Hash { int u,v,nxt; }h[N<<1]; int tt,hd[MOD]; int find(int i) { return f[i]==i?i:f[i]=find(f[i]); } inline void ins(int u,int v) { int key=((Lint)u*n+v)%MOD; h[++tt].u=u; h[tt].v=v; h[tt].nxt=hd[key]; hd[key]=tt; } inline int del(int u,int v) { int key=((Lint)u*n+v)%MOD; for (int k=hd[key];k;k=h[k].nxt) if (h[k].u==u&&h[k].v==v) return 1; return 0; } void init(void) { n=read(),m=read(); for (int i=1;i<=n;i++) f[i]=i; for (int i=1;i<=m;i++) ed[i][0]=read(),ed[i][1]=read(); q=read(); for (int i=1;i<=q;i++) { scanf("\n"),kind[i]=getchar(); cx[i]=read(),cy[i]=read(); if (kind[i]=='D') ins(cx[i],cy[i]),ins(cy[i],cx[i]); } for (int i=1;i<=m;i++) if (!del(ed[i][0],ed[i][1])) f[find(ed[i][0])]=find(ed[i][1]); } int res ; void work(void) { for (int i=q;i>=1;i--) kind[i]=='D'?f[find(cx[i])]=find(cy[i]):res[++res[0]]=find(cx[i])==find(cy[i]); for (int i=res[0];i>0;i--) printf("%c\n",res[i]?'C':'D'); } int main(void) { init(); work(); return 0; }
Sumarize
多次操作的离线算法有以下2种:①结合各种定序和存储方法,在遍历其他的时候顺便求解。
②得到最后一次的答案,反向推回来。
相关文章推荐
- Objective-C MD5 And SHA And HMAC-SHA
- ElasticSearch 2 (5) - Document APIs
- 自学adb命令
- requirejs data-main加载总是失败的问题
- Hive hiveserver2
- Xamarin开发Android之创建一个项目并调试
- iptables 设置
- 邮件服务器金牌服务是如何练成
- Zoj 3785 What day is that day?
- 漫天雪花效果
- js倒计时
- iOS iOS面试题及答案
- Hadoop平台架构--硬件篇
- Android Studio快捷键
- Laravel安装及运行项目
- Linux软连接和硬链接
- 【CodeVS】2597 团伙
- Flush Tables With Read Lock
- 来自一般大学的高被引学者
- iOS 去掉tabbar顶部的横线