hdu 1814 字典序最小的2sat(暴力深搜)
生活随笔
收集整理的這篇文章主要介紹了
hdu 1814 字典序最小的2sat(暴力深搜)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:
? ? ?題意就是最基礎(chǔ)的2sat,關(guān)系只有矛盾關(guān)系,然后二選一,關(guān)鍵是這個題目是輸出字典序最小的那組解。
思路:
? ? ?題意就是最基礎(chǔ)的2sat,關(guān)系只有矛盾關(guān)系,然后二選一,關(guān)鍵是這個題目是輸出字典序最小的那組解。
思路:
? ? ?輸出字典序最小,用強(qiáng)連通那個實(shí)現(xiàn)不了(起碼沒看到有人實(shí)現(xiàn)),其實(shí)我們可以直接暴力,我們可以給某個點(diǎn)染色,分成無色(W)紅色(R)和藍(lán)色(B)紅色是我們要的答案,對于每一個點(diǎn)我們先盡可能的吧他的a染成紅色,把他的~a染成藍(lán)色,如果發(fā)現(xiàn)矛盾,就是出現(xiàn)a是藍(lán)色的了,那么我們就把當(dāng)前這個連通塊重新清成W吧其實(shí)點(diǎn)換成~a這樣在繼續(xù)染色,如果還是不行,那么就證明無解。否則這樣全部染完色之后的紅色點(diǎn)就是我們要的點(diǎn)。時(shí)間復(fù)雜度是 n * m * 2,大約也就n * m左右。本以為會超時(shí),感覺到億了,結(jié)果沒有,1140ms AC ,貌似是有直接求什么字典序最小的固定算法吧!反正有也不會。哎!
#include<stdio.h> #include<string.h> #include<queue>#define N_node 16000 + 100 #define N_edge 40000 + 400 #define W 0 #define R 1 #define B 2 using namespace std;typedef struct {int to ,next; }STAR;STAR E[N_edge]; int list[N_node] ,tot; int col[N_node]; queue<int>q;void add(int a ,int b) {E[++tot].to = b;E[tot].next = list[a];list[a] = tot; }bool DFS(int s) {if(col[s] == B) return 0;if(col[s] == R) return 1;col[s] = R ,col[s^1] = B;q.push(s);for(int k = list[s] ;k ;k = E[k].next)if(!DFS(E[k].to)) return 0;return 1; }bool solve(int n) {memset(col ,W ,sizeof(col));for(int i = 0 ;i < n ;i ++){if(col[i]) continue;while(!q.empty()) q.pop();if(!DFS(i)){while(!q.empty()){col[q.front()] = col[q.front()^1] = W;q.pop();}if(!DFS(i^1)) return 0;}}return 1; }int main () {int n ,m ,i ,a ,b;while(~scanf("%d %d" ,&n ,&m)){memset(list ,0 ,sizeof(list)) ,tot = 1;for(i = 1 ;i <= m ;i ++){scanf("%d %d" ,&a ,&b);a-- ,b--;add(a ,b^1) ,add(b ,a^1);}if(solve(n * 2)){for(i = 1 ;i <= n * 2 ;i ++)if(col[i-1] == R) printf("%d\n" ,i);}else printf("NIE\n");}return 0; }
總結(jié)
以上是生活随笔為你收集整理的hdu 1814 字典序最小的2sat(暴力深搜)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu4115 2sat 石头剪刀布
- 下一篇: poj3648 2-sat 输出任意一组