CF27D Ring Road 2

Link

挺经典的题,是 P3209 [HNOI2010] 平面图判定 的无限弱化版。

考虑连边只会有两种情况,一种是连接的边在环内,一种是连接的边在环外,不妨定义在环内取 11,在环外取 00

如果两条边同时连在环内或者同时在环外有相交的话,这时候就出现矛盾了,很显然,如果其中任意一条边取 11 的话,那么剩下那条边就必须取 00

这就是一个很经典的 aba \oplus b 的格式了吧,对于这个我们当然可以考虑用 2-SAT 直接解决。

但是对于这种格式,我们同样可以通过二分图染色的方式进行解决,对于有矛盾的两条边直接对他们的编号连无向边,边的含义就是两端点不能同时颜色相同,钦定开始为 11 进行二分图染色,如果矛盾则无解。

#include<bits/stdc++.h>
using namespace std;
const int N =1e5+10;
vector<int> g[N<<1];
int n,m,c[N],vis[N],U[N],V[N],cal[N],flag;
bool vis1[N][3];
stack<int> sta;
void Add(int u,int v){
	g[u].push_back(v),g[v].push_back(u);
}
void color(int u,int col){
	vis[u]=1,c[u]=col;
	for(int i=0;i<g[u].size();i++){
		int v=g[u][i];
		if(c[v]!=0&&c[v]!=-col)	flag=false;
		if(c[v]==0)	color(v,-col);
	}
}
int main()
{
	flag=true;
	cin>>n>>m;
	for(int i=1;i<=m;i++)	cin>>U[i]>>V[i];
	for(int i=1;i<=m;i++)	if(U[i]>V[i])	swap(U[i],V[i]);
	for(int i=1;i<=m;i++)
		for(int j=i+1;j<=m;j++){
			if(i==j)	continue;
			if(U[i]==U[j]||V[i]==V[j])	continue;
			if((U[i]<U[j]&&V[i]>U[j]&&V[i]<V[j])||(U[i]>U[j]&&U[i]<V[j]&&V[i]>V[j]))	Add(i,j);
		}
	for(int i=1;i<=2*m-1;i++)	if(!vis[i])	color(i,1);
	if(flag==false)	cout<<"Impossible"<<endl;
	else{
		for(int i=1;i<=m;i++)	cout<<((c[i]==1)?"o":"i");
		cout<<endl;
	}
	return 0;
}
posted @   June_Failure  阅读(1)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示