码迷,mamicode.com
首页 > 其他好文 > 详细

poj2723-Get Luffy Out

时间:2014-10-05 00:04:07      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   os   使用   ar   for   sp   

一道2-SAT问题,每对钥匙需要加一条边,每扇门上的对应的要用的钥匙加一条边。

其实求解2-SAT问题,关键在于找到不能同时成立的条件,例如在本题中,每对钥匙不能同时使用,每扇门上的钥匙不能同时不使用。

 

 

  1 #include<cstdio>
  2 #include<vector>
  3 #include<cstring>
  4 using namespace std;
  5 
  6 const int maxn = 1<<12;
  7 
  8 struct TwoSAT
  9 {
 10     int n;
 11     vector<int> G[maxn*2];
 12     bool mark[maxn*2];
 13     int S[maxn*2], c;
 14 
 15     bool dfs(int x)
 16     {
 17         if (mark[x^1]) return false;
 18         if (mark[x]) return true;
 19         mark[x] = true;
 20         S[c++] = x;
 21         for (int i = 0; i < G[x].size(); i++)
 22             if (!dfs(G[x][i])) return false;
 23         return true;
 24     }
 25 
 26     void init(int n)
 27     {
 28         this->n = n;
 29         for (int i = 0; i < n*2; i++) G[i].clear();
 30         memset(mark, 0, sizeof(mark));
 31     }
 32 
 33     // x = xval or y = yval
 34     void add_clause(int x, int xval, int y, int yval)
 35     {
 36         x = x * 2 + xval;
 37         y = y * 2 + yval;
 38         G[x^1].push_back(y);
 39         G[y^1].push_back(x);
 40     }
 41 
 42     bool solve()
 43     {
 44         for(int i = 0; i < n*2; i += 2)
 45             if(!mark[i] && !mark[i+1])
 46             {
 47                 c = 0;
 48                 if(!dfs(i))
 49                 {
 50                     while(c > 0) mark[S[--c]] = false;
 51                     if(!dfs(i+1)) return false;
 52                 }
 53             }
 54         return true;
 55     }
 56 };
 57 
 58 
 59 ///////////////////////////////////////////////////////////////
 60 #include <iostream>
 61 TwoSAT solver;
 62 typedef pair<int ,int > CPair;
 63 #define K1 first
 64 #define K2 second
 65 CPair doors[1<<12];
 66 CPair keys[1<<12];
 67 int n;
 68 
 69 
 70 bool test(int nd)
 71 {
 72     solver.init(2*n);
 73     // 重新构图
 74     // 加入钥匙
 75     for(int i=0;i<n;i++)
 76     {
 77         solver.add_clause(keys[i].K1,1,keys[i].K2,1); // 1表示使用key,0表示不使用
 78     }
 79     // 加入门
 80     for(int i=0;i<=nd;i++)
 81     {
 82         solver.add_clause(doors[i].K1,0,doors[i].K2,0); // 1表示使用key,0表示不使用
 83     }
 84     return solver.solve();
 85 }
 86 
 87 int main()
 88 {
 89     #ifndef ONLINE_JUDGE
 90     freopen("in.txt","r",stdin);
 91     #endif
 92 
 93     int nDoor;
 94     while(scanf("%d %d",&n,&nDoor),n+nDoor)
 95     {
 96         // 添加一对钥匙
 97         for(int i=0;i<n;i++)
 98         {
 99             scanf("%d %d",&keys[i].K1,&keys[i].K2);
100         }
101 
102         //
103         for(int i=0;i<nDoor;i++)
104         {
105             scanf("%d %d",&doors[i].K1,&doors[i].K2);
106         }
107 
108         int L=0,R=nDoor-1;
109         while(L < R)
110         {
111             int M = L + (R-L+1)/2;
112             if(test(M)) L = M;
113             else R = M-1;
114         }
115         printf("%d\n",L+1);
116     }
117 
118     return 0;
119 }

 

poj2723-Get Luffy Out

标签:style   blog   color   io   os   使用   ar   for   sp   

原文地址:http://www.cnblogs.com/oneshot/p/4006458.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!