D38 2-SAT CF27D Ring Road 2
视频链接:D38 2-SAT CF27D Ring Road 2_哔哩哔哩_bilibili
CF27D Ring Road 2 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N=205; int n,m,x[N],y[N]; int dfn[N],low[N],stk[N],scc[N],tim,top,cnt; int head[N],idx; struct Edge{int to,ne;}e[20005]; void add(int a,int b){ e[++idx].to=b; e[idx].ne=head[a]; head[a]=idx; } void tarjan(int x){ dfn[x]=low[x]=++tim; stk[++top]=x; for(int i=head[x];i;i=e[i].ne){ int y=e[i].to; if(!dfn[y]){ //若y尚未访问 tarjan(y); low[x]=min(low[x],low[y]); } else if(!scc[y]) //若y已访问且未处理 low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]){ //若x是SCC的根 ++cnt; for(int y=-1;y!=x;) scc[y=stk[top--]]=cnt; } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d",&x[i],&y[i]); if(y[i]<x[i]) swap(x[i],y[i]); } for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) if(x[i]<x[j]&&x[j]<y[i]&&y[i]<y[j] ||x[j]<x[i]&&x[i]<y[j]&&y[j]<y[i]){ add(i,j+m); //i内j外 add(i+m,j); //i外j内 } for(int i=1;i<=2*m;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=m;i++) if(scc[i]==scc[i+m]) return puts("Impossible"),0; for(int i=1;i<=m;i++) scc[i]<scc[i+m]?putchar('i'):putchar('o'); }
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N=205; int n,m,x[N],y[N]; int dfn[N],low[N],stk[N],scc[N],tim,top,cnt; int head[N],idx; struct Edge{int to,ne;}e[20005]; void add(int a,int b){ e[++idx].to=b; e[idx].ne=head[a]; head[a]=idx; } void tarjan(int x){ dfn[x]=low[x]=++tim; stk[++top]=x; for(int i=head[x];i;i=e[i].ne){ int y=e[i].to; if(!dfn[y]){ //若y尚未访问 tarjan(y); low[x]=min(low[x],low[y]); } else if(!scc[y]) //若y已访问且未处理 low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]){ //若x是SCC的根 ++cnt; for(int y=-1;y!=x;) scc[y=stk[top--]]=cnt; } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d",&x[i],&y[i]); if(y[i]<x[i]) swap(x[i],y[i]); } for(int i=1;i<=m;i++) for(int j=i+1;j<=m;j++) if(x[i]<x[j]&&x[j]<y[i]&&y[i]<y[j] ||x[j]<x[i]&&x[i]<y[j]&&y[j]<y[i]){ add(i,j+m); add(j+m,i); add(i+m,j); add(j,i+m); } for(int i=1;i<=2*m;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=m;i++) if(scc[i]==scc[i+m]) return puts("Impossible"),0; for(int i=1;i<=m;i++) scc[i]<scc[i+m]?putchar('i'):putchar('o'); }