NBUT 1508 火烧赤壁2【离线+逆序并查集】
来源:互联网 发布:淘宝快捷回复短语大全 编辑:程序博客网 时间:2024/04/20 12:28
转载请注明出处:http://blog.csdn.net/a1dark
分析:由于这题N、M、T数据都非常大、于是我们要想办法优化一下、首先要离线、然后逆序查询、这样就不用每次重新构图、只需要每次把当前点的相关边、并入集合中、看连通块有多少、由于内存的限制、所以需要选择合理的存储结构、于是邻接表是必然的、具体见代码:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=200005;//题目要求数据int mpt[maxn];//用于并查集int num[maxn];//用于离线记录数据int ans[maxn];//用于保存答案int vis[maxn];//用于标记是否在集合中int n,m,temp;//N个点、M条边、temp表示答案的变量struct node{ int to,next;//用于临界表存储}map[maxn*2];int head[maxn];int k;//临界表索引void add(int x,int y){//邻接表添加边 k++; map[k].to=y; map[k].next=head[x]; head[x]=k;}void init(){//初始化并查集 for(int i=0;i<n;i++){ mpt[i]=i; }}int find(int x){//寻找祖先并压缩路劲 int r=x; while(r!=mpt[r]){ r=mpt[r]; } int b=x; int f; while(b!=r){ f=mpt[b]; mpt[b]=r; b=f; } return r;}void merge(int x,int y){//合并两个点 int fx=find(x); int fy=find(y); if(fx!=fy){ mpt[fx]=fy; temp--;//若祖先不同则合并后少一个连通块 }}int main(){ while(scanf("%d%d",&n,&m)!=EOF){ memset(vis,0,sizeof(vis)); memset(num,0,sizeof(num)); init(); temp=n; k=-1;//初始化邻接表 for(int i=0;i<maxn;i++) head[i]=-1; int a,b; for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); add(a,b);//加入邻接表 add(b,a); } int test; scanf("%d",&test); for(int i=0;i<n;i++)//初始化标记数组 vis[i]=0; for(int i=1;i<=test;i++){ scanf("%d",&num[i]); vis[num[i]]=1; } init();//初始化并查集 temp=n-test; for(int i=0;i<n;i++){ if(vis[i]==0){ int now=i; for(int j=head[now];j!=-1;j=map[j].next){//重新构图 int s=map[j].to; if(vis[s]==0){ merge(now,s); vis[now]=0; } } } } ans[test+1]=temp;//讲答案逆序保存进ans数组中 temp++;//每一次多一个点则+1 for(int i=test;i>=1;i--){//循环test次 int now=num[i]; vis[now]=0; for(int j=head[now];j!=-1;j=map[j].next){//找相邻的边 int s=map[j].to; if(vis[s]==0){//若相邻的边在图上、则合并 merge(now,s); vis[now]=0; } } ans[i]=temp;//记录当前答案 temp++; } for(int i=1;i<=test+1;i++)//输出答案 printf("%d\n",ans[i]); } return 0;}
- NBUT 1508 火烧赤壁2【离线+逆序并查集】
- NOJ——1508火烧赤壁2(并查集+启发式合并+逆序加边)
- nbut 1058 火烧赤壁 2
- NOJ[1508] 火烧赤壁2
- 【ZOJ3261】【离线并查集】【逆序】【好题】
- 火烧赤壁的故事
- 火烧赤壁 洛谷 vijos
- 洛谷p1496火烧赤壁
- 2774 火烧赤壁(排序贪心)
- Codeforces 722C Destroying Array【逆序(离线)思维+并查集】
- 离线的并查集
- 离线+并查集 Portal
- NBUT 1451 Elise (map +并查集)
- 1165 火烧赤壁 vijosoj (数组模拟)
- vijos 1165_火烧赤壁_离散
- HDU 3938 离线并查集
- hdu 3938(离线并查集)
- LCA Tarjin 并查集 离线
- NS2教程
- 回溯法------ 解数独游戏(2)
- Scale up和Scale out
- 使用cvCanny函数时注意的问题
- ubuntu使用相关文章存档
- NBUT 1508 火烧赤壁2【离线+逆序并查集】
- 每天一个linux命令(52):ifconfig命令
- pthread_cleanup_push/pop
- FFMPeg代码分析:AVFrame结构体及其相关的函数
- 每天一个linux命令(53):route命令
- 每天一个linux命令(54):ping命令
- hibernate+java+sql 之间数据类型转换关系
- hadoop2.0介绍(二)
- 每天一个linux命令(55):traceroute命令