P4171 [JSOI2010] 滿漢全席 2-SAT

Showball發表於2024-05-19

P4171 [JSOI2010] 滿漢全席 2-SAT

題目連結

思路

2-SAT模板題,我們將滿席定為1,漢席定為0.那麼建邊即可。判斷同一道菜滿漢是否在強聯通分量中即可。

注意多測清空!!!

程式碼

vector<int> e[N];
stack<int> stk;
int dfn[N],low[N],tot;
int instk[N],scc[N],siz[N],cnt;
int n,m;

void tarjan(int u){
  dfn[u]=low[u]=++tot;
  stk.push(u);instk[u]=1;
  for(auto v:e[u]){
    if(!dfn[v]){
      tarjan(v);
      low[u]=min(low[u],low[v]);
    }else if(instk[v]) low[u]=min(low[u],dfn[v]);    
  }
  if(dfn[u]==low[u]){
    int v;++cnt;
    do{
      v=stk.top();
      stk.pop();
      instk[v]=0;
      scc[v]=cnt;
      siz[cnt]++;
    }while(v!=u);
  }  
}

void init(){
  tot=0,cnt=0;
  for(int i=0;i<2*n;i++){
    e[i].clear();
    instk[i]=0;
    dfn[i]=low[i]=0;
  } 
  for(int i=1;i<=cnt;i++){
    siz[i]=0;
    scc[i]=0;
  } 
}
void Showball(){
  cin>>n>>m;
  init();
  while(m--){
    char x,y;
    int u,v;
    cin>>x>>u>>y>>v;
    u--;v--;
    e[(u<<1)+!(x=='m')].pb((v<<1)+(y=='m'));
    e[(v<<1)+!(y=='m')].pb((u<<1)+(x=='m'));
  }

  for(int i=0;i<2*n;i++){
    if(!dfn[i]) tarjan(i);
  }
  for(int i=0;i<n;i++){
    if(scc[i<<1]==scc[i<<1|1]) return cout<<"BAD\n",void();
  }
  cout<<"GOOD\n";
}

相關文章