日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

poj3648 2-sat 输出任意一组解

發布時間:2025/6/17 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj3648 2-sat 输出任意一组解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 一對夫妻結婚,請來了n對夫妻,所有人坐在同一張桌子上吃飯,這張桌子是長方形的可以坐兩排人,有如下限制
(1) 新娘和新郎不做同一側。
(2) 每對來的夫妻也不能坐在同一側。?
(3) 有一些人有曖昧關系(男女,男男,或者女女),有曖昧關系的兩

個人不可以同時坐在新娘對面。


輸出一組可行解,輸出的是坐在新娘對面的人。


思路:

? ? ?根據限制關系,而且還是二選一,顯然這個是2sat,對于每個人,都拆成兩個點,一個是a表示坐在新娘這一側,另一個是~a表示坐在新郎這一側,則對于任何有曖昧關系的,要么一邊坐一個,要不同時坐在新娘這一側,則只要他們兩個中至少有一個1就行了,建圖是這樣 ~a -> b ,~b?-> a,對于每一對,他們不能坐在同一側則不能相同,建圖是 a -> ~b ,b?-> ~a ,~a ->b ,~b -> a ,還有就是新娘必須坐在新娘這側,直接 ~a?-> a.


#include<stdio.h> #include<string.h> #include<stack>#define N_node 5000 #define N_edge 100000 #define R 1 #define B 2using namespace std;typedef struct {int to ,next; }STAR;STAR E1[N_edge] ,E2[N_edge]; int list1[N_node] ,list2[N_node] ,tot; int Belong[N_node] ,cnt; int mark[N_node] ,Col[N_node]; stack<int>st ,stt;void add(int a ,int b) {E1[++tot].to = b;E1[tot].next = list1[a];list1[a] = tot;E2[tot].to = a;E2[tot].next = list2[b];list2[b] = tot; }void DFS1(int s) {mark[s] = 1;for(int k = list1[s] ;k ;k = E1[k].next)if(!mark[E1[k].to]) DFS1(E1[k].to);st.push(s) ,stt.push(s); }void DFS2(int s) {mark[s] = 1;Belong[s] = cnt;for(int k = list2[s] ;k ;k = E2[k].next)if(!mark[E2[k].to]) DFS2(E2[k].to); }bool solve(int n) {memset(mark ,0 ,sizeof(mark));while(!st.empty()) st.pop();while(!stt.empty()) stt.pop();for(int i = 0 ;i < 4 * n ;i ++)if(!mark[i]) DFS1(i);memset(mark ,0 ,sizeof(mark)) ,cnt = 0;while(!st.empty()){int xin = st.top();st.pop();if(mark[xin]) continue;cnt ++;DFS2(xin);}for(int i = 0 ;i < n * 4 ;i += 2)if(Belong[i] == Belong[i^1]) return 0;return 1; }int main () {int i ,n ,m ,a ,b;char c1 ,c2;while(~scanf("%d %d" ,&n ,&m) && n + m){memset(list1 ,0 ,sizeof(list1));memset(list2 ,0 ,sizeof(list2)) ,tot = 1;for(i = 1 ;i <= m ;i ++){scanf("%d%c%d%c" ,&a ,&c1 ,&b ,&c2);a = a * 2 + (c1 == 'h' ? 1 : 0);b = b * 2 + (c2 == 'h' ? 1 : 0);add(a * 2 + 1 ,b * 2);add(b * 2 + 1 ,a * 2);} for(i = 0 ;i < n ;i ++){a = i * 2 ,b = i * 2 + 1;add(a * 2 + 1 ,b * 2) ,add(b * 2 + 1 ,a * 2);add(a * 2 ,b * 2 + 1) ,add(b * 2 ,a * 2 + 1);}add(1 ,0);if(!solve(n)){printf("bad luck\n");continue;}memset(Col ,0 ,sizeof(Col));while(!stt.empty()){i = stt.top() ,stt.pop();if(Col[i]) continue;Col[i] = B ,Col[i^1] = R;}int mk = 0;for(i = 4 ;i < n * 4 ;i += 2){ if(Col[i] == B) continue;if(mk) printf(" ");mk = 1;printf("%d" ,i / 4);i % 4 > 1 ? printf("h") : printf("w");}puts("");}return 0; }

總結

以上是生活随笔為你收集整理的poj3648 2-sat 输出任意一组解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。