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');
}

 

posted @ 2024-08-05 18:33  董晓  阅读(72)  评论(0编辑  收藏  举报