POJ3648 2 sat強連通縮點法

2021-09-20 18:49:31 字數 1458 閱讀 1766

題意:有一對新人結婚,邀請n對夫婦去參加婚禮。有一張很長的桌子,人只能坐在桌子的兩邊,還要滿足下面的要求:1.每對夫婦不能坐在同一側 2.n對夫婦之中可能有通姦關係(包括男男,男女,**),有通姦關係的不能同時坐在新娘的對面,可以分開坐,可以同時坐在新娘這一側。如果存在一種可行的方案,輸出與新娘同側的人。

解析:分析可知用2-sat選擇與新郎同側的人,那麼與新娘同側的人就對應知道了,這樣求解答案會簡單很多。在建圖過程中要注意,新娘和新郎中必須選擇新郎,因此要從新娘到新郎連一條邊,剩下就是經典的tarjan縮點+拓撲排序求答案了。

**如下:

#include#include#include#include#include#include#includeusing namespace std;

const int maxn=1005*2;

int low[maxn],dfn[maxn],st[maxn],num[maxn],belong[maxn],in[maxn],cf[maxn];

int top,index,scc;

int color[maxn];

bool instack[maxn];

vectorg[maxn];

vector> dag;

void tarjan(int now)

else if(instack[to]&&low[now]>dfn[to])

low[now]=dfn[to];

}if(low[now]==dfn[now])

while(now!=to);

}}bool solvable(int n)

while(!q.empty())

int siz=dag[now].size();

for(int i=0;i另:發現用hdu1814的染色法同樣可以解決此問題,而且**實現難度要小得多,複雜度卻幾乎相同,難道強連通分量縮點法有什麼特別的用處嗎?求各路大牛指點....

**如下:

#include#include#include#include#include#include#includeusing namespace std;

const int maxn=1005*2;

vectorg[maxn];

bool v[maxn];

int st[maxn],top;

bool dfs(int u)

return true;

}bool twosat(int n)

}}int get(char s)

if(s[i]=='w')

return res*2;

return res*2+1;

}int main()

g[0].push_back(1);

if(twosat(2*n))

}else printf("bad luck\n");

}return 0;

}

POJ3648 2SAT解的求得

include include include include include include using namespace std const int nn 100 const int mm 1000 struct twosat void addedge int u,int v void tar...

poj 2553強連通 縮點

先吐槽下,剛開始沒看懂題,以為只能是乙個連通圖0t0 題意 給你乙個有向圖,求g圖中從v可達的所有點w,也都可以達到v,這樣的v稱為sink.求這樣的v.解 求強連通 縮點。求所有出度為0的點即為要求的點。注意 可能有多個聯通分支。include include include define n 5...

poj 2186 強連通縮點

題意 有n只奶牛,奶牛有自己認為最受歡迎的奶牛。奶牛們的這種 認為 是單向可傳遞的,當a認為b最受歡迎 b不一定認為a最受歡迎 且b認為c最受歡迎時,a一定也認為c最受歡迎。現在給出m對這樣的 認為.的關係,問有多少只奶牛被除其本身以外的所有奶牛關注。思路 既然有單向傳遞關係,那麼關係圖可能就形成了...