CF27D Ring Road 2
挺经典的题,是 P3209 [HNOI2010] 平面图判定 的无限弱化版。
考虑连边只会有两种情况,一种是连接的边在环内,一种是连接的边在环外,不妨定义在环内取 ,在环外取 。
如果两条边同时连在环内或者同时在环外有相交的话,这时候就出现矛盾了,很显然,如果其中任意一条边取 的话,那么剩下那条边就必须取 。
这就是一个很经典的 的格式了吧,对于这个我们当然可以考虑用 2-SAT 直接解决。
但是对于这种格式,我们同样可以通过二分图染色的方式进行解决,对于有矛盾的两条边直接对他们的编号连无向边,边的含义就是两端点不能同时颜色相同,钦定开始为 进行二分图染色,如果矛盾则无解。
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现