标签:方法 force main pac init def 2-sat print its
在这题上不是标准的“a或b”这样的语句,因此需要进行一些转化来进行建边。同时在这题上点数较多,用lrj大白书上的做法会T,因此采用求强连通分量的方法来求解(对一个点,如果其拓扑序大于其为真的那个点,则这个语句为真,都相同则无解,否则为假)。AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5 + 5; 4 typedef long long ll; 5 6 int n,m,dfs_clock,dfn[N*2],low[N*2]; 7 int belong[N*2],scc_cnt; 8 stack<int> S; 9 vector<int> G[N*2]; 10 11 void init() 12 { 13 for(int i=1;i<=n;i++) G[i].clear(); 14 dfs_clock = 0; 15 memset(dfn,0,sizeof(dfn)); 16 memset(belong,0,sizeof(belong)); 17 scc_cnt = 0; 18 } 19 20 void tarjan(int u) 21 { 22 dfn[u]=low[u]=++dfs_clock; 23 S.push(u); 24 for(int i=0;i<G[u].size();i++) 25 { 26 int v = G[u][i]; 27 if(!dfn[v]) 28 { 29 tarjan(v); 30 low[u]=min(low[u],low[v]); 31 } 32 else if(!belong[v]) 33 { 34 low[u]=min(low[u],dfn[v]); 35 } 36 } 37 if(low[u]==dfn[u]) 38 { 39 scc_cnt++; 40 for(;;) 41 { 42 int x = S.top();S.pop(); 43 belong[x] = scc_cnt; 44 if(x==u) break; 45 } 46 } 47 } 48 49 void add(int x, int y) {G[x].push_back(y);} 50 51 void solve() 52 { 53 for(int i=0;i<2*m;i++) 54 { 55 if(!dfn[i]) tarjan(i); 56 } 57 vector<int> ans; 58 59 for(int i=0;i<2*m;i+=2) 60 { 61 if(belong[i] == belong[i+1]) 62 { 63 puts("No"); 64 return ; 65 } 66 else 67 { 68 if(belong[i] > belong[i+1]) ans.push_back(i/2+1); 69 } 70 } 71 puts("Yes"); 72 printf("%d\n",ans.size()); 73 for(int i=0;i<ans.size();i++) printf("%d%c",ans[i],i==ans.size()-1?‘\n‘:‘ ‘); 74 } 75 76 vector<int> v[N]; 77 78 int main() 79 { 80 cin >> n >> m; 81 for(int i=1;i<=n;i++) 82 { 83 int t; scanf("%d",&t); 84 while(t--) 85 { 86 int x; scanf("%d",&x); 87 v[i].push_back(x); 88 } 89 } 90 init(); 91 for(int i=1;i<n;i++) 92 { 93 int sz = min(v[i].size(), v[i+1].size()); 94 int pos = -1; 95 for(int j=0;j<sz;j++) 96 { 97 if(v[i][j] != v[i+1][j]) 98 { 99 pos = j; 100 break; 101 } 102 } 103 if(pos == -1) 104 { 105 if(v[i].size() <= v[i+1].size()) continue; 106 else return 0*puts("No"); 107 } 108 int x = v[i][pos]-1; 109 int y = v[i+1][pos]-1; 110 if(x < y) 111 { 112 add(y<<1|1, x<<1|1); 113 add(x<<1, y<<1); 114 } 115 else 116 { 117 add(x<<1, x<<1|1); 118 add(y<<1|1, y<<1); 119 } 120 } 121 solve(); 122 return 0; 123 }
Codeforces 876E National Property ——(2-SAT)
标签:方法 force main pac init def 2-sat print its
原文地址:http://www.cnblogs.com/zzyDS/p/7771630.html