2-XOR-SAT

【题目描述】
SAT(Satisfiability,可满足性)问题是著名的 NP 完全问题,它的内容是:判断由有限个
布尔变量及其“非”用“或”操作连接起来的表达式组是否可以都为 TRUE。
2-SAT 问题对 SAT 问题做了如下限制:每个表达式由两个变量构成。
XOR-SAT 问题对 SAT 问题做了如下限制:表达式仅由变量与“异或”操作构成。

2-XOR-SAT 问题包含了以上两个限制,即:有 n 个布尔变量?1 …?? 与 m 个双变量
异或方程
你需要判断方程组是否有解,如果有解请输出任意一组解,否则输出无解。
【输入文件】
第一行两个整数 n m
接下来m行,每行两个整数 a? b? 及一个大写字符串 c? ,c? 为”TRUE”或”FALSE”
【输出文件】
若无解,则输出一行”Impossible”
若有解,则第一行输出”Possible”,接下来?行输出?1 …?? 的值”TRUE”或”FALSE”
【样例输入】
3 2
1 2 TRUE
2 3 FALSE
【样例输出】
Possible
FALSE
TRUE
TRUE
【数据范围】
30%的数据保证 n ≤ 20;m ≤ 20
100%的数据保证 1 ≤ n ≤ 100,000;1 ≤ m ≤ 100,000

考虑把不同的x连边,相同u,v的转换

可以理解u与v+n不同,u+n与v不同

一个点i与i+n显然不同

然后就可以黑白染色

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 struct Node
 8 {
 9     int next,to;
10 } edge[800001];
11 int num,head[200001],n,m;
12 int vis[200001];
13 char s[201];
14 void add(int u,int v)
15 {
16     num++;
17     edge[num].next=head[u];
18     head[u]=num;
19     edge[num].to=v;
20 }
21 bool dfs(int x,int col)
22 {int i;
23     vis[x]=col;
24     for (i=head[x];i;i=edge[i].next)
25     {
26         int v=edge[i].to;
27         if (vis[v]==-1)
28         {
29             dfs(v,col^1);
30         }
31         else if (vis[v]==vis[x]) 
32         {
33             cout<<"Impossible\n";
34             exit(0);
35         }
36     }
37 }
38 int main()
39 {
40     int u,v,i;
41     cin>>n>>m;
42     for (i=1;i<=n;i++)
43     add(i,n+i),add(n+i,i);
44     for (i=1; i<=m; i++)
45     {
46         scanf("%d%d%s",&u,&v,s);
47         if (s[0]=='F')
48         {
49             add(v+n,u);
50             add(u,v+n);
51             add(u+n,v);
52             add(v,u+n);
53         }
54         else if (s[0]=='T')
55         {
56             add(u,v);
57             add(v,u);
58         }
59     }
60     memset(vis,-1,sizeof(vis));
61     for (i=1; i<=n; i++)
62         if (vis[i]==-1)
63         {
64             dfs(i,1);
65         }
66     cout<<"Possible"<<endl;
67     for (i=1;i<=n;i++)
68     if (vis[i]==1) printf("TRUE\n");
69     else printf("FALSE\n");
70 }

 

转载于:https://www.cnblogs.com/Y-E-T-I/p/7761657.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值