首页 > 其他分享 >「HNOI2019」校园旅行

「HNOI2019」校园旅行

时间:2022-08-24 21:14:39浏览次数:52  
标签:二分 旅行 连通 int 校园 奇偶性 cnt 奇环 HNOI2019

将相邻且颜色相同的点视作一个连通块,若该连通块是二分图,那么从连通块中一点\(x\)到连通块中一点\(y\)的路径的奇偶性确定

所以对于块外一点\(x\)到块内一点\(y\),可以将它们的路径在连通块内的部分看作在一条边上反复横跳(这样奇偶性不变且当路径长度不够时可以凑长度),然后决定是否走出这条边而走向下一条边

所以在二分图中,环没有必要存在,只需要它的最小生成树即可(二分图的环的作用就是凑长度,而反复横跳一条边也可以达成这一目的,且二者都不会改变奇偶性)

若不是连通块,也就是存在奇环,那么奇偶性就会发生变化(奇环走一圈),所以奇环不能用反复横跳来替代

所以在非二分图的连通块中,我们只需要保留一个奇环即可,而为了方便,我们可以随机给一个节点连一条自环

#include<bits/stdc++.h>
#define pr pair<int,int>
#define fi first
#define se second
using namespace std;
const int N=5e3+5,M=5e5+5,MN=1e6+5e3+5;
int n,m,Q;
char s[N];
int head[N],cnt;
struct node{
	int v,nxt;
}tree[MN];
void add(int x,int y){
	tree[++cnt].v=y,tree[cnt].nxt=head[x],head[x]=cnt;
}
vector<int> edge[N];
bool flag[N][N];
queue<pr> q;

void add1(int x,int y){
	flag[x][y]=flag[y][x]=1,q.push(pr(x,y));
}
int color[N];
bool f;
void dfs(int x,int now){
	color[x]=now;
	for(int i=0,y;i<edge[x].size();++i){
		y=edge[x][i];
		if(s[x]==s[y]){
			if(color[x]==color[y]) f=true;
			if(color[y]!=-1) continue;
			add1(x,y),add(x,y),add(y,x);
			dfs(y,now^1);
		}
	}
}
bool vis[N];
void dfs1(int x){
	vis[x]=true;
	for(int i=0,y;i<edge[x].size();++i){
		y=edge[x][i];
		if(s[x]!=s[y]&&!vis[y]) add(x,y),add(y,x),dfs1(y);
	}
}
void solve(){
	int x,y;
	while(q.size()){
		x=q.front().fi,y=q.front().se,q.pop();
		for(int i=head[x],x1;i;i=tree[i].nxt)
			for(int j=head[y],y1;j;j=tree[j].nxt){
				x1=tree[i].v,y1=tree[j].v;
				if(s[x1]==s[y1]&&!flag[x1][y1]) add1(x1,y1);
			}
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&Q);
	getchar(); cin>>s+1;
	for(int i=1,u,v;i<=m;++i) scanf("%d%d",&u,&v),edge[u].push_back(v),edge[v].push_back(u);
	for(int i=1;i<=n;++i) add1(i,i),color[i]=-1; 
	for(int i=1;i<=n;++i){
		f=false;
		if(color[i]!=-1) continue;
		dfs(i,1);
		if(f) add(i,i);
	}
	for(int i=1;i<=n;++i) if(!vis[i]) dfs1(i);
	solve();
	while(Q--){
		int u,v; scanf("%d%d",&u,&v);
		printf(flag[u][v]?"YES\n":"NO\n");
	}
	return 0;
}

标签:二分,旅行,连通,int,校园,奇偶性,cnt,奇环,HNOI2019
From: https://www.cnblogs.com/LuoyuSitfitw/p/16621560.html

相关文章

  • 基于MFC和C++的校园导航系统
    基于MFC和C++的校园导航系统基于MFC和C++实现校园导航系统项目简介设计一款面向广大师生和外来办公或参观人员的校园导航系统,为校外人员来校办事提供便利。校园导航系......
  • 校园内的汽车
    https://www.acwing.com/problem/content/description/1587/思路:电话记录的模型,先筛选出所有符合要求的记录,之后按照题目要求做即可。#include<iostream>#include<c......
  • 1026 [NOIP2001]Car的旅行路线 标点建图 勾股定理 floyd
     链接:https://ac.nowcoder.com/acm/contest/26077/1026来源:牛客网题目描述又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个......
  • 暑假集训五[星际旅行, 砍树, 超级树, 求和]
    暑假集训5星际旅行这个题刚看我觉得很ex,没事思路,就跳了,然后就去欺负\(T4\)了后来别的不会做,然后回来肝它...就肝出来了...对了,注意开\(longlong\)首先转化一下题意,我......
  • 牛的旅行
    P1522[USACO2.4]牛的旅行CowTours-洛谷|计算机科学教育新生态(luogu.com.cn)dfs为图中的连通块染色floyd求出任意两点的最短距离,不连通就INF求出每个连通块中......