【BZOJ 2199] [USACO11JAN]大陸会議ザコンチネンタルCowngress(2-SAT)
フェイス質問
問題は少し、長い顔
分析
問題に依存に問題を考えてみましょう
これに変換牛はちょうど限り最初の投票用紙を満たしていない牛は、他を満たすように、二回投票、:私たちは、それぞれが2票を投じる牛は一票と、少なくとも最終的な結果一貫した変換を持って置きます依存関係の問題。
2つのポイントに分割された各紙幣は、Yは、Aが満たしていないチケットに接続されているN、点の各点を表し最初のエッジが2-SATを実行満たします
ない従来のアルゴリズムはtarjan場合Yを決定した場合、Nを観察することができるデータ範囲\(N- \のLeq 1000と、m個の\のLeq 4000 \)、i番目の紙幣の直接列挙の判定結果は、各時間YはNであり、その後、矛盾がないかどうかを確認するために、対応するBFS 2つのスプリットポイントから開始します。2つの点が矛盾していない場合は、出力?。
時間複雑度\(O(N(N + M))\)
コード
//Tarjan+拓扑不好判断?的情况,暴力dfs
//xi为A或xj为B 转化为 xi为B且xj为A
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#define maxn 1000
using namespace std;
int n,m;
vector<int>E[maxn*2+5];
void add_edge(int u,int v){
// printf("%d %d\n",u,v);
E[u].push_back(v);
}
int mark[maxn*2+5];
void dfs(int x){
mark[x]=1;
for(int y : E[x]){
if(!mark[y]) dfs(y);
}
}
bool check(int x){
for(int i=1;i<=n*2;i++) mark[i]=0;
dfs(x);
for(int i=1;i<=n;i++){
if(mark[i]&&mark[i+n]) return 0;
}
return 1;
}
char ans[maxn+5];
int main(){
char op1[2],op2[2];
int u,v,p,q;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d %s %d %s",&u,op1,&v,op2);
if(op1[0]=='Y') p=1;
else p=0;
if(op2[0]=='Y') q=1;
else q=0;
add_edge(u+n*p,v+n*(1-q));
/*
i为Y,i+n为N
举例理解,如果op1和op2为Y,N
那么第一个询问是N,不满足,对应的点就是u+1*n,第二个询问是N,满足,对应的点就是v+1*n
*/
add_edge(v+n*q,u+n*(1-p));
}
bool flag1,flag2;
for(int i=1;i<=n;i++){
flag1=check(i);
flag2=check(i+n);
if(!flag1&&!flag2){
printf("IMPOSSIBLE\n");
return 0;
}else if(flag1&&!flag2){
ans[i]='Y';
}else if(!flag1&&flag2){
ans[i]='N';
}else{
ans[i]='?';
}
}
for(int i=1;i<=n;i++) printf("%c",ans[i]);
}