52ky 发表于 2022-5-2 10:08:02

LOJ 1251(2-SAT+输出一组可行解)

想法:u表示留下,~u表示离开,类似v,对于+u,-v,我们可以这样定义:如果你离开,那么v必须留下,如果v离开,那么你必须留下,所以我们可以连接边 u+n->v,v+n->u,下面同样如此。


1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<算法>
5 #include<堆栈>
6 #include<向量>
7 #include<队列>
8 使用命名空间标准;
9 #define MAXN 20000
10 #define MAXM 444444
11
12 结构边{
13 int v,下一个;
14 }边;
15
16 int n,m,NE;
17 整数头;
18
19 无效插入(int u,int v)
20 {
21 边.v=v;
22 边缘.next=head;
23 头=NE++;
二十四 }
25
26 int cnt,bcc_count;
27 int low,dfn,color;
28 布尔标记;
29 堆栈<int>S;
30
31 无效的 Tarjan (int u)
32 {
33 低=dfn=++cnt;
34 标记=真;
35 S.push(u);
36 for(int i=head;i!=-1;i=edge.next){
37 int v=edge.v;
38 如果(dfn==0){
39 塔里扬(五);
40 低=min(低,低);
41 }否则如果(标记){
42 低=min(低,dfn);
43 }
44 }
45 如果(低==dfn){
46 诠释诉;
47 bcc_count++;
48 做{
49 v=S.top();
50 S.pop();
51 标记=假;
52 颜色=bcc_count;
53 }而(u!=v);
54 }
55 }
56
57 int opp;
58 布尔法G()
59 {
60 for(int i=1;i<=n;i++){
61 如果(颜色==颜色)返回假;
62 //opp 存储与编号为x的连通分量相矛盾的连通分量的编号
63 opp[颜色]=颜色;
64 opp[颜色]=颜色;
65 }
66返回真;
67 }
68
69 向量<向量<int> >g;
70 个向量<int>ans;
71 int 度;
72 int vis;
73
第74章
75 {
76 队列<int>que;
77 for(int i=1;i<=bcc_count;i++){
78 if(度==0)que.push(i);
79 }
80 而(!que.empty()){
81 int u=que.front();
82 que.pop();
83 如果(vis==0){
84 //染色
85 可见=1;
86 vis]=-1;
87 }
88 for(int i=0;i<g.size();i++){
89度]--;
90 if(度]==0)que.push(g);
91}
92 }
93}
94
95
96 int main()
97 {
98 int _case,t=1,a,b,u,v;
99 scanf("%d",&_case);
100 而(_case--){
101 scanf("%d %d",&m,&n);
102 NE=0;
103 memset(头,-1,大小(头));
第104章
105 scanf("%d%d",&a,&b);
106 u=abs(a),v=abs(b);
107 if(a>0&&b>0)插入(u+n,v),插入(v+n,u);
108 else if(a>0&&b<0)Insert(u+n,v+n),Insert(v,u);
109 else if(a<0&&b>0)Insert(u,v),Insert(v+n,u+n);
110 否则插入(u,v+n),插入(v,u+n);
111 }
112 cnt=bcc_count=0;
113 memset(标记,假,sizeof(标记));
114 memset(dfn,0,sizeof(dfn));
115 memset(颜色,0,sizeof(颜色));
116 for(int i=1;i<=2*n;i++)if(dfn==0)Tarjan(i);
117 printf("案例 %d:",t++);
第118章
119 放置(“否”);
120继续;
121 }
122 次放置(“是”);
123 //反向映射
124 memset(度,0,大小(度));
125 g.clear();
126 g.resize(2*n+2);
127 for(int u=1;u<=2*n;u++){
128 for(int i=head;i!=-1;i=edge.next){
129 int v=edge.v;
130 如果(颜色!=颜色){
131 g[颜色].push_back(颜色);
132度[颜色]++;
133 }
134 }
135 }
136 memset(vis,0,sizeof(vis));
第137章
第138章
139 for(int i=1;i<=n;i++){
140 if(vis]==1)ans.push_back(i);
141 }
142 printf("%d",(int)ans.size());
143 排序(ans.begin(),ans.end());
144 for(int i=0;i<(int)ans.size();i++){
145 printf("%d",ans);
146 }
147 放置(“”);
148 }
149 返回 0;
150 }
查看代码

(Idea: u means to stay, ~ U means to leave, similar to v. for + U, - V, we can define this: if you leave, then V must stay, if V leaves, then you must stay, so we can connect edges U + n - > V, V + n - > u, the same below.1 #include<iostream>2 #include<cstdio>3 #include<cstring>4 #include < algorithm >5 #include < stack >6 #include < vector >7 #include < queue >8. Use namespace standards;9 #define MAXN 2000010 #define MAXM 444444eleven12 structural edge{13 int V, next;14} sides ;fifteen16 int n,m,NE;17 integer header ;eighteen19 invalid insert (int u, int V)20 {21 side v=v;22 edge next=head;23 heads = ne + +;Twenty four}twenty-five26 int cnt,bcc_ count;27 int low,dfn,color;28 Boolean marker ;29 stack < int > s;thirty31 invalid tarjan (int U)32 {33 low = DFN = + CNT;34 mark = true;35 S.push(u);36 for(int i=head;i!=-1;i=edge.next){37 int v=edge. v;38 If (DFN = = 0){39 talijan (V);40 low = min (low , low );41} otherwise (mark ){42 low = min (low , DFN );43 }44 }45 If (low = = DFN ){46. Interpretation litigation;47 bcc_ count++;48 do{49 v=S.top();50 S.pop();51 mark = false;52 color = BCC_ count;53} (U! = V);54 }55 }fifty-six57 int opp;58 judge bull ()59 {60 for(int i=1;i<=n;i++){61 If (color = = color ) returns false;62 / / OPP stores the number of the connected component that contradicts the connected component numbered X63 OPP ] = color ;64 OPP ] = color ;65 }66 return true;67 }sixty-eight69 vector < vector < int > > G;70 vectors < int > ans;71 int degrees ;72 int vis;seventy-threeChapter 7475 {76 cohort < int > que;77 for(int i=1;i<=bcc_count;i++){78 if (degree = = 0) que push(i);79 }80 (! Que. Empty()){81 int u=que. front();82 que. pop();83 if (VIS = = 0){84 / / staining85 visible = 1;86 vis]=-1;87 }88 for(int i=0;i<g.size(); i++){89 degrees ]--;90 if (degree ] = = 0) que push(g);91}92 }93}ninety-fourninety-five96 int main()97 {98 int _ case,t=1,a,b,u,v;99 scanf("%d",&_case);100 (_case --){101 scanf("%d %d",&m,&n);102 NE=0;103 memset (header, - 1, size (header));Chapter 104105 scanf("%d%d",&a,&b);106 u=abs(a),v=abs(b);107 if (a > 0 & & b > 0) insert (U + N, V), insert (V + N, U);108 else if(a>0&&b<0)Insert(u+n,v+n),Insert(v,u);109 else if(a<0&&b>0)Insert(u,v),Insert(v+n,u+n);110 otherwise, insert (U, V + n), insert (V, U + n);111 }112 cnt=bcc_ count=0;113 memset (mark, false, sizeof);114 memset(dfn,0,sizeof(dfn));115 memset (color, 0, sizeof);116 for(int i=1;i<=2*n;i++)if(dfn==0)Tarjan(i);117 printf ("case% d:", t + +);Chapter 118No ("no");120 continue;121 }122 placements ("yes");123 / / reverse mapping124 memset (degree, 0, size (degree));125 g.clear();126 g.resize(2*n+2);127 for(int u=1;u<=2*n;u++){128 for(int i=head;i!=-1;i=edge.next){129 int v=edge. v;130 if (color ! = color ){131 G ] push_ Back (color );132 degrees ] + +;133 }134 }135 }136 memset(vis,0,sizeof(vis));Chapter 137Chapter 138139 for(int i=1;i<=n;i++){140 if(vis]==1)ans.push_ back(i);141 }142 printf("%d",(int)ans.size());143 sorting (ans.begin(), ans.end());144 for(int i=0;i<(int)ans.size(); i++){145 printf("%d",ans);146 }147 placement ("");148 }149 returns 0;150 }view code)



页: [1]
查看完整版本: LOJ 1251(2-SAT+输出一组可行解)