题意:有一个环,现给你一些区间的起点与终点,区间可以在环内,可以在环外,但是在环内环外的区间都不能彼此相交,问可能否,如果可能,输出方案。
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; }