【GDKOI2011】反恐任务

news/2024/7/20 22:11:34 标签: 深度优先, 图论, 算法

题目大意

给你一个 n n n 个点和 m m m 条边的无向图,并有 Q Q Q 个询问,每次询问有两种形式:
1.1 X Y P Q , 表示在删掉 P P P Q Q Q 之间的连边后 X X X Y Y Y 是否相互可达(保证 P P P Q Q Q 有边相连)
2.2 X Y P,表示在删掉点 P P P X X X Y Y Y 是否相互可达。
若可达,输出 y e s yes yes ,否则输出 n o no no

数据范围

n ≤ 1 0 5 , m ≤ 5 ∗ 1 0 5 , Q ≤ 5 ∗ 1 0 5 n \le 10^5 ,m \le 5*10^5 ,Q \le 5*10^5 n105,m5105,Q5105

思路

看到删掉点或边是否可达,我们可以想到割点和桥,倘若删掉的点或边不为割点或桥,那就证明互相可达(前提是 X X X Y Y Y 互相可达)。
对于求割点和桥,我们可以用 T a r j a n Tarjan Tarjan 预处理出来每一个点的 d f s dfs dfs d f n i dfn_{i} dfni 以及每个点可以到达的最小的节点(双亲除外)的最小深度优先数(即 d f n dfn dfn) l o w i low_{i} lowi ,然后我们就可以用所处理出来的 d f n dfn dfn l o w low low 搞事情 解题啦!

删边操作:
1.若 X X X Y Y Y 不在一个连通图里: 输出 n o no no
2.若边 ( P , Q ) (P,Q) (P,Q) 不为桥:输出 y e s yes yes
3.若点 X X X Y Y Y 均在 P ( Q ) P(Q) P(Q) 的子树内,如图:
在这里插入图片描述
肯定有一条路径不经过边 ( P , Q ) (P,Q) (P,Q) 的,输出 y e s yes yes
4.若点 X X X 和点 Y Y Y 均不在点 P ( Q ) P(Q) P(Q) 内(和上图一样),输出 y e s yes yes
5.剩余情况:输出 n o no no

删点操作
同样要先判断 X X X Y Y Y 是否在同一连通图内部。
若点 P P P 不为割点,输出 y e s yes yes 即可。
然后判断 X X X Y Y Y P P P 的哪颗子树,如图:
在这里插入图片描述
设点 y a ya ya 为点 X X X 在点 P P P 的儿子 y a ya ya 的子树内,点 y b yb yb 为点 Y Y Y 在点 P P P 的儿子 y b yb yb 的子树内。
1.若点 X X X 和点 Y Y Y均不在 P P P 的子树内(如 x 1 , y 1 x1,y1 x1,y1),输出 y e s yes yes
2.若点 X X X 和点 Y Y Y 均在 P P P 的子树内(如 x 2 , y 2 x2,y2 x2,y2):
如果 l o w y a > d f n p low_{ya} > dfn_{p} lowya>dfnp l o w y b > d f n p low_{yb}>dfn_{p} lowyb>dfnp (即点 X X X 和点 Y Y Y均有一条路径可以连向 P P P的祖先),输出 y e s yes yes ,否则输出 n o no no
3.若点 X X X 和点 Y Y Y 其一在 P P P 的子树内(如 x 3 , y 3 x3,y3 x3,y3),设点 Y Y Y 在点 P P P 的子树内:
如果 l o w y b > d f n p low_{yb}>dfn_{p} lowyb>dfnp (即 Y Y Y 有一条路径可以到达 P P P 的祖先),输出 y e s yes yes ,否则输出 n o no no

求是否在子树内可以处理出每个点的子树大小 s i z e size size
求为那个儿子内可以用倍增在线求,也可以用栈离线求。
分类讨论较多,但实质不难,细心点就可以通过了。

AC代码

#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
	int head,to,nxt;
}edge[1000200];
struct pu{
	int dfn,dep,low,wz,sz,col;
}tree[1000200];
int n,m,a,b,opt,Q,cnt,sta[1000200],top,tot,f[200200][22],sc;
bool vis[1000200],in_stack[1000200];
bool ge[1000200],isbridge[1000200];
void xx(int u,int v)
{
	edge[cnt].to=v;
	edge[cnt].nxt=edge[u].head;
	edge[u].head=cnt;
	cnt++;
}
void tarjan(int x,int father,int col)
{
	
	vis[x]=1;
	tot++,top++;
	sta[top]=tot;
	in_stack[x]=1;
	tree[x].low=tree[x].dfn=tot;
	tree[x].col=col,tree[x].dep=tree[father].dep+1;
	tree[x].sz=1;
//	printf("!!!%d %d\n",x,tree[x].low);
	for(int i=1;(1<<i)<=tree[x].dep;i++)
	f[x][i]=f[f[x][i-1]][i-1];
	for(int i=edge[x].head;i!=-1;i=edge[i].nxt)
	{
		int y=edge[i].to;
		if(y==father)
		continue;
//		printf("!!!%d %d\n",x,y);
		if(!vis[y])
		{
			f[y][0]=x;
			tarjan(y,x,col);
			tree[x].sz+=tree[y].sz;
			tree[x].low=min(tree[x].low,tree[y].low);
		}
		else if(in_stack[y])
		tree[x].low=min(tree[x].low,tree[y].dfn);
	}
}
int lca(int u,int v)
{
	if(tree[u].dep<tree[v].dep)
	swap(u,v);
	for(int i=20;i>=0;i--)
	{
		if(tree[f[u][i]].dep>=tree[v].dep)
		u=f[u][i];
		if(u==v)
		return u;
	}
	for(int i=20;i>=0;i--)
	{
		if(f[u][i]!=f[v][i])
		u=f[u][i],v=f[v][i];
	}
	return f[u][0];
}
int find_son(int x,int y)
{
	for(int i=20;i>=0;i--)
	if(tree[f[x][i]].dep>tree[y].dep)
	x=f[x][i];
	return x;
}
bool in(int x,int y)
{
	if(tree[y].dfn<=tree[x].dfn&&tree[y].dfn+tree[y].sz-1>=tree[x].dfn)
	return 1;
	return 0;
}
int main()
{
//	freopen("check.in","r",stdin);
//	freopen("a.out","w",stdout);
	memset(edge,-1,sizeof(edge));
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    scanf("%d %d",&a,&b),xx(a,b),xx(b,a);
    for(int i=1;i<=n;i++)
    if(!vis[i])
    tarjan(i,0,i);    
//	printf("!\n");
//    int qwq=0;
	scanf("%d",&Q);
    while(Q--)
    {
    	scanf("%d",&opt);
//    	qwq++;
//    	printf("%d ",qwq);
    	if(opt==1)
    	{
    		int x,y,p,q;
    		scanf("%d %d %d %d",&x,&y,&p,&q);
    		int LCA=lca(x,y);
    		if(tree[x].dfn<tree[y].dfn)
    		swap(x,y);
    		if(tree[p].dfn<tree[q].dfn)
    		swap(p,q);
    		if(tree[x].col!=tree[y].col)
    		{
    			printf("no\n");
    			continue;
			}
			if(tree[p].low<=tree[q].dfn)
			{
				printf("yes\n");
				continue; 
			}
			if((in(x,p)&&in(y,p))||(!in(x,p)&&!in(y,p)))
			{
				printf("yes\n");
				continue;
			}
			printf("no\n");
			continue;
		}
		else
		{
		    int x,y,p;
			scanf("%d %d %d",&x,&y,&p);
			int LCA=lca(x,y);
			if(tree[x].col!=tree[y].col)
			{
				printf("no\n");
				continue;
			}
			if(x==p||y==p)
			{
				printf("no\n");
				continue;
			}
			if(!in(x,p)&&!in(y,p))
			{
			    printf("yes\n");	
			    continue;
			} 
			if(in(y,p))
			swap(x,y);
			if(!in(y,p))
			{
				int ya=find_son(x,p);
				if(tree[ya].low<tree[p].dfn)
				printf("yes\n");
				else
				printf("no\n");
				continue;
			}
			else
			{
				int ya=find_son(x,p),yb=find_son(y,p);
				if(tree[ya].low<tree[p].dfn&&tree[yb].low<tree[p].dfn||ya==yb)
				printf("yes\n");
				else
				printf("no\n");
				continue;
			}
		} 
	}
} 

http://www.niftyadmin.cn/n/1318768.html

相关文章

Spring中@Autowired标签与@Resource标签的区别

Spring不但支持自己定义的Autowired注解&#xff0c;还支持由JSR-250规范定义的几个注解&#xff0c;如&#xff1a;Resource、 PostConstruct及PreDestroy。 1. Autowired Autowired是Spring 提供的&#xff0c;需导入 Package:org.springframework.beans.factory.annot…

数据库查询优化方案

优化数据库查询操作 1.对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断&#xff0c;否则将导致引擎放弃使用索引而进行全表扫描&#xff0c;如&#xff1a;…

splayLCT学习笔记

1.伸展树(splay) 1.1性质 伸展树是一颗二叉搜索树&#xff0c;可以在 O(logn)O(log n)O(logn) 的时间内完成加入&#xff0c;删除&#xff0c;查询操作。 一般的二叉搜索树会被卡成一条链&#xff0c;而伸展树是依靠在维护二叉搜索树的同时&#xff0c;使得这颗树的深度尽可能…

Unix/Linux下如何使用Vi编辑器

vi 的工作模式 Vi 在初始启动后首先进入编辑模式&#xff0c;这时用户可以利用一些预先定义的按键来移动光标、删除文字、 复制或粘贴文字等。这些按键均是普通的字符&#xff0c;例如 l 是向右移动光标&#xff0c;相当于向右箭头键&#xff0c;k 是 向下移动光标&#xff0c;…

spring3中新增的@value注解

今天在开发过程中&#xff0c;发现在Controller层的类&#xff0c;无法像Servicen层的类那样直接通过Value("${fileUpload.fileName}")方式注入配置值到对象中。原因是因为在xml中有如下配置&#xff0c;将配置有Controller注解的Action类&#xff08;包名有action&a…

【GDKOI2013】贪吃蛇 题解

题目大意&#xff1a; 给出一张大小为 n∗mn*mn∗m 的矩阵&#xff0c;每一块都有一个权值 ai,ja_{i,j}ai,j​ &#xff0c;可以随机选择起点&#xff0c;并且只能向右拐或向前走&#xff0c;不能碰到走过的路或走出图&#xff0c;求走过的路径权值和最大为多少。 数据范围&a…

数据库设计注意要点

在一个项目开始初期&#xff0c;数据库的设计非常重要&#xff0c;很多时候&#xff0c;我们只关心和考虑到眼前的功能&#xff0c;而忽略了后续的可维护性和可拓展性&#xff0c;以及还有一个在大数据时代会遇到的高并发问题。  在设计表结构时要注意以下几个要点&#xff1…

九封信

有时候&#xff0c;莫名的心情不好&#xff0c;不想和任何人说话&#xff0c;只想一个人静静的发呆。有时候&#xff0c;想一个人躲起来脆弱&#xff0c;不愿别人看到自己的伤口。有时候&#xff0c;走过熟悉的街角&#xff0c;看到熟悉的背影&#xff0c;突然想起一个人的脸。…