hdu3715 二分+2sat+建图
生活随笔
收集整理的這篇文章主要介紹了
hdu3715 二分+2sat+建图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 給你一個遞歸公式,每多一層就多一個限制,問你最多能遞歸多少層。
思路:
? ? ?先分析每一層的限制 x[a[i]] + x[b[i]] != c[i],這里面x[] = 0,1,c[i] = 0,1,2
? ? ? 給你一個遞歸公式,每多一層就多一個限制,問你最多能遞歸多少層。
思路:
? ? ?先分析每一層的限制 x[a[i]] + x[b[i]] != c[i],這里面x[] = 0,1,c[i] = 0,1,2
如果我們把 x[]=0,1想成取或不取,就是基礎的關系,那么這個題目就可以直接抽象成2sat問題,然后我們二分去枚舉深度,每次根據2sat的結果判斷二分走向,我的2sat用的是雙深搜的強連通,用那個t打頭的也行,隨意,這樣這個題目就ok了,對了下面總結下2sat的建圖吧,這個題目也能用上。
#include<stdio.h> #include<string.h> #include<stack>#define N_node 500 + 10 #define N_edge 100000 + 100 using 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]; int A[11000] ,B[11000] ,C[11000]; stack<int>st;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); }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 ok(int mid ,int n) {memset(list1 ,0 ,sizeof(list1));memset(list2 ,0 ,sizeof(list2));tot = 1;for(int i = 1 ;i <= mid ;i ++){int x = A[i] * 2 ,xx = A[i] * 2 + 1;int y = B[i] * 2 ,yy = B[i] * 2 + 1;if(C[i] == 0) add(xx ,y) ,add(yy ,x);if(C[i] == 1) add(x ,y) ,add(y ,x) ,add(xx ,yy) ,add(yy ,xx);if(C[i] == 2) add(y ,xx) ,add(x ,yy);}memset(mark ,0 ,sizeof(mark));while(!st.empty()) st.pop();for(int i = 0 ;i < n * 2 ;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);}int mk = 0; for(int i = 0 ;i < n * 2 && !mk ;i += 2)if(Belong[i] == Belong[i^1]) mk = 1;return !mk; }int main () {int t ,n ,m ,i;scanf("%d" ,&t);while(t--){scanf("%d %d" ,&n ,&m);for(i = 1 ;i <= m ;i ++)scanf("%d %d %d" ,&A[i] ,&B[i] ,&C[i]);int low ,mid ,up ,ans = 0;low = 0 ,up = m;while(low <= up){mid = (low + up) >> 1;if(ok(mid ,n))ans = mid ,low = mid + 1;else up = mid - 1;}printf("%d\n" ,ans);}return 0; }
總結
以上是生活随笔為你收集整理的hdu3715 二分+2sat+建图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu3622 二分+2sat
- 下一篇: hdu1815 2sat + 二分 +