题意:有一个环,现给你一些区间的起点与终点,区间可以在环内,可以在环外,但是在环内环外的区间都不能彼此相交,问可能否,如果可能,输出方案。
2-SAT。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=205;
const int MaxN=11005;
const int MaxE=51005;
struct Edge
{
int u,v,pre;
Edge(){}
Edge(int u,int v,int pre) :
u(u),v(v),pre(pre) {}
}edge[N*10];
int hBef[N],hAft[N],nEdge;
int n,m,L[N],R[N];
bool insta[MaxN];
int lab[MaxN],nLab;
int sta[MaxN],top;
int dfn[MaxN],low[MaxN],idx;
int deg[MaxN],color[MaxN],other[MaxN];
struct Tarjan_directed
{
void init()
{
nLab=top=idx=0;
memset(lab,-1,sizeof(lab));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(insta,0,sizeof(insta));
memset(deg,0,sizeof(deg));
}
void dfs(int u)
{
insta[u]=1;
sta[top++]=u;
dfn[u]=low[u]=++idx;
for(int i=hBef[u];i!=-1;i=edge[i].pre)
{
int v=edge[i].v;
if(!dfn[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(insta[v]&&dfn[v]<low[u]) low[u]=dfn[v];
}
if(low[u]==dfn[u])
{
++nLab; int tmp;
do
{
tmp=sta[--top];
insta[tmp]=0;
lab[tmp]=nLab;
}while(tmp!=u);
}
}
void solve()
{
for(int i=0;i<n*2;i++) if(dfn[i]==0) dfs(i);
}
}tar;
void addEdge(int u,int v,int head[])
{
edge[nEdge]=Edge(u,v,head[u]);
head[u]=nEdge++;
}
void edgeInit()
{
nEdge=0;
memset(hBef,-1,sizeof(hBef));
memset(hAft,-1,sizeof(hAft));
}
bool Intersect(int L1,int R1,int L2,int R2)
{
if(L1>L2) swap(L1,L2),swap(R1,R2);
if(L1==L2&&R1<R2) swap(L1,L2),swap(R1,R2);
if(R1<=L2) return false;
if(R2<=R1) return false;
return true;
}
void BuildGraph()
{
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++) if(Intersect(L[i],R[i],L[j],R[j]))
{
addEdge(i,j+n,hBef);
addEdge(j,i+n,hBef);
addEdge(i+n,j,hBef);
addEdge(j+n,i,hBef);
}
}
}
void RebuildGraph()
{
int tmp=nEdge;
for(int i=0;i<tmp;i++)
{
int u=lab[edge[i].u],v=lab[edge[i].v];
if(u-v)
{
addEdge(v,u,hAft); deg[u]++;
}
}
}
bool HasAns()
{
for(int i=0;i<n;i++)
{
int u=lab[i],v=lab[i+n];
other[u]=v; other[v]=u;
if(u==v)
{
puts("Impossible");
return false;
}
}
return true;
}
void TopSort()
{
memset(color,0,sizeof(color));
queue<int> que;
for(int i=1;i<=nLab;i++) if(deg[i]==0) que.push(i);
while(que.size())
{
int u=que.front(); que.pop();
if(color[u]==0)
{
color[u]=1;
color[other[u]]=2;
}
for(int i=hAft[u];i!=-1;i=edge[i].pre)
{
int v=edge[i].v;
if(--deg[v]==0) que.push(v);
}
}
}
void OutputAns()
{
for(int i=0;i<n;i++)
{
if(color[lab[i]]==1) putchar('i');
else putchar('o');
}
puts("");
}
void TwoSAT()
{
BuildGraph();
tar.init(); tar.solve();
if(HasAns()==0) return;
RebuildGraph();
TopSort();
OutputAns();
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
edgeInit();
for(int i=0;i<n;i++)
{
scanf("%d%d",&L[i],&R[i]);
if(L[i]>R[i]) swap(L[i],R[i]);
}
TwoSAT();
}
return 0;
}