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

几个关于2-sat的题

时间:2019-09-23 22:46:45      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:class   map   建图   传送门   expand   tom   contain   pos   mile   

几个关于2-sat的题

 

HDU3062

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3062

题意:

从2n个人去宴会,有 m条关系 i和j不能同时去 夫妻不能同时去 问能否有n个人出席

题解:

因为是n对夫妻,我们将编号扩展 奇数是丈夫,偶数是妻子

那么m条关系就是 i*2+a 和j*2+b不能同时出席

建边 选b必选 a‘

选a必选b‘

然后判断是否在一个强连通分量里面即可

 

代码:

/**
*        ┏┓    ┏┓
*        ┏┛┗━━━━━━━┛┗━━━┓
*        ┃       ┃  
*        ┃   ━    ┃
*        ┃ >   < ┃
*        ┃       ┃
*        ┃... ⌒ ...  ┃
*        ┃       ┃
*        ┗━┓   ┏━┛
*          ┃   ┃ Code is far away from bug with the animal protecting          
*          ┃   ┃   神兽保佑,代码无bug
*          ┃   ┃           
*          ┃   ┃       
*          ┃   ┃
*          ┃   ┃           
*          ┃   ┗━━━┓
*          ┃       ┣┓
*          ┃       ┏┛
*          ┗┓┓┏━┳┓┏┛
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛
*/
// warm heart, wagging tail,and a smile just for you!
//
//                           _ooOoo_
//                           o8888888o
//                           88" . "88
//                           (| -_- |)
//                           O\ = /O
//                       ____/`---‘\____
//                     .‘ \|     |// `.
//                     / \||| : |||// \
//                   / _||||| -:- |||||- \
//                   |   | \ - /// |   |
//                   | \_| ‘‘\---/‘‘ |   |
//                   \ .-\__ `-` ___/-. /
//                 ___`. .‘ /--.--\ `. . __
//               ."" ‘< `.___\_<|>_/___.‘ >‘"".
//             | | : `- \`.;`\ _ /`;.`/ - ` : | |
//             \ \ `-.   \_ __\ /__ _/   .-` / /
//         ======`-.____`-.___\_____/___.-`____.-‘======
//                           `=---=‘
//       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//                     佛祖保佑     永无BUG
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 2e3 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
LL gcd(LL a, LL b) {
   return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
   return a / gcd(a, b) * b;
}
double dpow(double a, LL b) {
   double ans = 1.0;
   while(b) {
       if(b % 2)ans = ans * a;
       a = a * a;
       b /= 2;
  } return ans;
}
LL quick_pow(LL x, LL y) {
   LL ans = 1;
   while(y) {
       if(y & 1) {
           ans = ans * x % mod;
      } x = x * x % mod;
       y >>= 1;
  } return ans;
}
struct EDGE {
   int v, nxt;
} edge[maxn * maxn];
int n, m;
int head[maxn], tot;
void add_edge(int u, int v) {
   edge[tot].v = v;
   edge[tot].nxt = head[u];
   head[u] = tot++;
}
int low[maxn], dfn[maxn], num, in[maxn], scc[maxn];
int Stack[maxn], top, cnt;
void tarjan(int u) {
   low[u] = dfn[u] = ++num;
   Stack[top++] = u;
   in[u] = 1;
   for(int i = head[u]; i != -1; i = edge[i].nxt) {
       int v = edge[i].v;
       if(!dfn[v]) {
           tarjan(v);
           low[u] = min(low[u], low[v]);
      } else if(in[v]) {
           low[u] = min(low[u], dfn[v]);
      }
  }
   if(low[u] == dfn[u]) {
       int v;
       cnt++;
       do {
           v = Stack[--top];
           in[v] = 0;
           scc[v] = cnt;
      } while(u != v);
  }
}
bool Two_sat() {
   for(int i = 0; i < 2 * n; i++) {
       if(!dfn[i]) {
           tarjan(i);
      }
  }
   for(int i = 0; i < n; i++) {
       if(scc[i * 2] == scc[i * 2 + 1]) return false;
  }
   return true;
}
int main() {
#ifndef ONLINE_JUDGE
   FIN
#endif
   while(~scanf("%d%d", &n, &m)) {
       memset(head, -1, sizeof(head));
       memset(dfn, 0, sizeof(dfn));
       memset(low, 0, sizeof(low));
       memset(scc, 0, sizeof(scc));
       tot = 0;
       num = 0;
       top = 0;
       cnt = 0;
       for(int i = 1; i <= m; i++) {
           int a, vala;
           int b, valb;
           scanf("%d%d%d%d", &a, &b,  &vala, &valb);
           a = a * 2 + vala;
           b = b * 2 + valb;
           add_edge(a, b ^ 1);  //选A必选B‘
           add_edge(b, a ^ 1);  //选B必选A‘
      }
       if(Two_sat()) {
           printf("YES\n");
?
      } else {
           printf("NO\n");
      }
  }
   return 0;
}

洛谷P4782

传送门:https://www.luogu.org/problem/P4782

题意:

2-sat模板题

题解:

建边

为或为?

?

建图

代码:

/**
*        ┏┓    ┏┓
*        ┏┛┗━━━━━━━┛┗━━━┓
*        ┃       ┃  
*        ┃   ━    ┃
*        ┃ >   < ┃
*        ┃       ┃
*        ┃... ⌒ ...  ┃
*        ┃       ┃
*        ┗━┓   ┏━┛
*          ┃   ┃ Code is far away from bug with the animal protecting          
*          ┃   ┃   神兽保佑,代码无bug
*          ┃   ┃           
*          ┃   ┃       
*          ┃   ┃
*          ┃   ┃           
*          ┃   ┗━━━┓
*          ┃       ┣┓
*          ┃       ┏┛
*          ┗┓┓┏━┳┓┏┛
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛
*/
// warm heart, wagging tail,and a smile just for you!
//
//                           _ooOoo_
//                           o8888888o
//                           88" . "88
//                           (| -_- |)
//                           O\ = /O
//                       ____/`---‘\____
//                     .‘ \|     |// `.
//                     / \||| : |||// \
//                   / _||||| -:- |||||- \
//                   |   | \ - /// |   |
//                   | \_| ‘‘\---/‘‘ |   |
//                   \ .-\__ `-` ___/-. /
//                 ___`. .‘ /--.--\ `. . __
//               ."" ‘< `.___\_<|>_/___.‘ >‘"".
//             | | : `- \`.;`\ _ /`;.`/ - ` : | |
//             \ \ `-.   \_ __\ /__ _/   .-` / /
//         ======`-.____`-.___\_____/___.-`____.-‘======
//                           `=---=‘
//       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//                     佛祖保佑     永无BUG
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 2e6 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
LL gcd(LL a, LL b) {
   return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
   return a / gcd(a, b) * b;
}
double dpow(double a, LL b) {
   double ans = 1.0;
   while(b) {
       if(b % 2)ans = ans * a;
       a = a * a;
       b /= 2;
  } return ans;
}
LL quick_pow(LL x, LL y) {
   LL ans = 1;
   while(y) {
       if(y & 1) {
           ans = ans * x % mod;
      } x = x * x % mod;
       y >>= 1;
  } return ans;
}
struct EDGE {
   int v, nxt;
} edge[maxn << 1];
   int n, m;
int head[maxn], tot;
void add_edge(int u, int v) {
   edge[tot].v = v;
   edge[tot].nxt = head[u];
   head[u] = tot++;
}
int low[maxn], dfn[maxn], num,in[maxn],scc[maxn];
int Stack[maxn],top, cnt;
void tarjan(int u) {
   low[u] = dfn[u] = ++num;
   Stack[top++] = u;
   in[u] = 1;
   for(int i = head[u]; i != -1; i = edge[i].nxt) {
       int v = edge[i].v;
       if(!dfn[v]) {
           tarjan(v);
           low[u] = min(low[u], low[v]);
      } else if(in[v]) {
           low[u] = min(low[u], dfn[v]);
      }
  }
   if(low[u] == dfn[u]) {
       int v;
       cnt++;
       do {
           v = Stack[--top];
           in[v] = 0;
           scc[v] = cnt;
      } while(u != v);
  }
}
bool Two_sat() {
   for(int i = 1; i <= 2 * n; i++) {
       if(!dfn[i]) {
           tarjan(i);
      }
  }
   for(int i = 1; i <= n; i++) {
       if(scc[i] == scc[i + n]) return false;
  }
   return true;
}
int main() {
#ifndef ONLINE_JUDGE
   FIN
#endif
   memset(head, -1, sizeof(head));
   tot = 0;
?
   scanf("%d%d", &n, &m);
   for(int i = 1; i <= m; i++) {
       int a, vala;
       int b, valb;
       scanf("%d%d%d%d", &a, &vala, &b, &valb);
       int nota = !vala;
       int notb = !valb;
       add_edge(a + nota * n, b + valb * n);
       add_edge(b + notb * n, a + vala * n);
  }
   if(Two_sat()) {
       printf("POSSIBLE\n");
       for(int i = 1; i <= n; i++) {
           printf("%d ", scc[i] > scc[i + n]);
      }
  } else {
       printf("IMPOSSIBLE\n");
  }
   return 0;
}

 

几个关于2-sat的题

标签:class   map   建图   传送门   expand   tom   contain   pos   mile   

原文地址:https://www.cnblogs.com/buerdepepeqi/p/11575096.html

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