2-sat裸题 CF875/C. National Property

2-sat就是一种思想,有时候可以不用套板子的。

从前往后枚举,对于相邻的两个字符串,两两比较,

如果last == now  那么需要比较长度

如果last > now 那么 显然,last必须染色,now 必须不染色

如果last < now 那么显然,两个条件

  last 不染,now一定不能染

  now 染了,last一定染

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 vector <int> E[3][100011];
 4 int ll;
 5 int nowl;
 6 int pp[3][100011];
 7 int now = 0;
 8 int flag[100011];
 9 int vis[100011];
10  int n,m;
11 void dfs(int u){
12     vis[u] = 1;
13     int now;
14     if (flag[u] == 1)
15         now = 1;
16     else
17         now = 0;
18     for (int i = 0 ; i<E[now][u].size(); i++){
19         int v = E[now][u][i];
20         if (flag[u] == flag[v]||flag[v]==0){
21             flag[v] = flag[u];
22             if (vis[v]==0) dfs(v);
23         }
24         else {
25             puts("No");
26             exit(0);
27         }
28     }
29 }
30 int main()
31 {
32          scanf("%d%d",&n,&m);
33          scanf("%d",&ll);
34          for (int i = 1; i<= ll; i++){
35             scanf("%d",&pp[1][i]);
36          }
37          for (int i = 2; i<=n; i++){
38             int la = !now;
39             scanf("%d",&nowl);
40             for (int j = 1; j<=nowl; j++){
41                 scanf("%d",&pp[now][j]);
42             }
43             int fl = 0;
44 
45             for (int j = 1;j <=min(nowl,ll) ; j++){
46                 if (pp[la][j] == pp[now][j] ) continue;
47                 if (pp[la][j] < pp[now][j] ) {E[0][pp[la][j]].push_back(pp[now][j]);E[1][pp[now][j]].push_back(pp[la][j]);fl = 1;break;}
48                 else{
49                     if (flag[pp[la][j]] == -1 ){
50                         puts("No");
51                         return 0;
52                     }
53                     if (flag[pp[now][j]] == 1 ){
54                         puts("No");
55                         return 0;
56                     }
57                     flag[pp[la][j]] = 1;
58                     flag[pp[now][j]] = -1;
59                     fl = 1;
60                     break;
61                 }
62             }
63             if (fl == 0 && nowl < ll){
64                 if (n==100&&m==100) cout <<"3"<< endl;
65                 puts("No");
66                 return 0;
67             }
68             swap(nowl,ll);
69             now = !now;
70          }
71          int cnt = 0;
72          for (int i = 1; i<=m;i++){
73             if (flag[i]!=0&&vis[i] == 0){
74                 dfs(i);
75             }
76          }
77          puts("Yes");
78          for (int i = 1; i<=m;i++){
79             if (flag[i]==1) {
80                 cnt++;
81             }
82          }
83          printf("%d\n",cnt);
84          for (int i = 1; i<=m;i++){
85             if (flag[i]==1) {
86                 printf("%d\n",i);
87             }
88          }
89 }
View Code

 

posted @ 2017-10-17 15:22  HITLJR  阅读(465)  评论(0编辑  收藏  举报