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 }

 

posted @ 2017-10-31 15:11  Z-Y-Y-S  阅读(377)  评论(0编辑  收藏  举报