hdu-1814(2-sat)
阿新 • • 發佈:2018-11-01
dfs div true max 方案 ostream ack %d ems
題意:給你n個組,m條規則,每組有倆個人,這兩個人不能同時出現,然後m條規則代表著有兩個人,這兩個人也不能同時出現,問你是否存在每組都能出現一人的選擇方案
解題思路:因為這個需要字典序輸出,所以只能用暴力的方法解決,如果x,y在同一條規則裏面,那麽建立一條邊由x指向和y同一組的另一個人,y也這樣做,然後開始暴力dfs
代碼:
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<queue> #include<vector> #define oth(x) (x%2==0?x-1:x+1) using namespace std; const int maxn=20050; int n,m,cnt; bool mark[maxn]; vector<int>e[maxn]; int ans[maxn]; bool dfs(int x) { if(mark[oth(x)]) return false; if(mark[x]) return true; mark[x]=true; ans[++cnt]=x; for(int i=0;i<e[x].size();i++) if(!dfs(e[x][i])) return false; return true; } bool twosat() { memset(mark,0,sizeof(mark)); for(int i=1;i<=n;i+=2) { if(!mark[i]&&!mark[oth(i)]) { cnt=0; if(!dfs(i)) { for(int j=1;j<=cnt;j++) mark[ans[j]]=mark[oth(ans[j])]=0; if(!dfs(oth(i))) return false; } } } return true; } int main() { int x,y; while(scanf("%d%d",&n,&m)!=EOF) { n=n*2; for(int i=0;i<=n;i++) e[i].clear(); for(int i=1;i<=m;i++) { cin>>x>>y; e[x].push_back(oth(y)); e[y].push_back(oth(x)); } if(twosat()) { for(int i=1;i<=n;i+=2) { if(mark[i]) printf("%d\n",i); else printf("%d\n",i+1); } } else printf("NIE\n"); } }
hdu-1814(2-sat)