Codeforces Round #348 (VK Cup 2016 Round 2) E F (2-sat. 待补)
来源:互联网 发布:专情的网络语句 编辑:程序博客网 时间:2024/04/29 02:26
E Little Artem and 2-SAT
题意给两个包含n个变量形式如下的2-sat f和g
求一种取值使两个2-sat的结果不同
法一:2-sat建图缩点,若两个都无解或只有一个有解就很好办,讨论两个都有解的情况,枚举f中的变量x,若x和!x在一条路径上(如:x -> ... -> !x) 而在g中不是,则可取x=1(或!x = 1),导致f无解,而g不影响。若不存在这样的变量,则枚举x和y, 经过同样的处理即可得出答案。
法二:枚举f中的一个x or y,尝试x=0 && y=0,看g能不能有解,而有解的情况就是g的dag中x和y能到达的点中不同时存在i和!i
法一代码
#include <stdio.h>#include <bits/stdc++.h>using namespace std;#define eps 1e-9#define LL long long #define ULL unsigned long long#define N (2000 + 10)#define M (3000000 + 10)#define inf 0x3f3f3f3fint n, m1, m2;int get(int x) {if(x < 0) return n-x;return x;}struct graph{ int fst[N], vv[M], nxt[M], e;int S[N], tot, low[N], pre[N], dc, sccno[N], scnt;vector<int> g;bitset<N> son[N];void init() {memset(fst, -1, sizeof fst);e = 0;}void add(int u, int v) {vv[e] = v, nxt[e] = fst[u], fst[u] = e++;}void dfs(int u) {pre[u] = low[u] = ++dc;S[tot++] = u;for(int i = fst[u]; ~i; i = nxt[i]) {int v = vv[i];if(!pre[v]) {dfs(v);low[u] = min(low[u], low[v]);}else if(!sccno[v]) {low[u] = min(low[u], pre[v]);}}if(low[u] == pre[u]) {++scnt;while(tot) {int x = S[--tot];sccno[x] = scnt;if(x == u) break;}}}void find_scc() {tot = dc = scnt = 0;memset(pre, 0, sizeof pre);memset(sccno, 0, sizeof sccno);for(int i = 1; i <= n*2; ++i) if(!pre[i]) dfs(i);}void scan(int m) {int u, v;init();for(int i = 0; i < m; ++i) {scanf("%d%d", &u, &v);add(get(-u), get(v));add(get(-v), get(u));}find_scc();}bool judge() {for(int i = 1; i <= n; ++i) {if(sccno[i] == sccno[i+n]) return 0;}return 1;}void output() {for(int i = 1; i <= n; ++i) {printf("%d%c", sccno[i] < sccno[i+n] ? 1 : 0, i == n ? '\n': ' ' );}}void getbit() {for(int u = 1; u <= 2*n; ++u) {for(int i = fst[u]; ~i; i = nxt[i]) {int v = vv[i];son[sccno[u]][sccno[v]] = 1;}}for(int i = 1; i <= scnt; ++i) {son[i][i] = 1;for(int j = 1; j <= scnt; ++j) {if(son[j][i])son[j] |= son[i];}}}}g[2];bool gao(int a, int b) {int k = 0;for(int i = 1; i <= n; ++i) {int u = g[k].sccno[i+a], v = g[k].sccno[i+b];int uu = g[k^1].sccno[i+a], vv = g[k^1].sccno[i+b];if(g[k].son[u][v] != g[k^1].son[uu][vv]) {if(g[k].son[u][v]) k ^= 1;g[k].add(i+b, i+a);g[k].find_scc();g[k].output();return 1;}}return 0;}int main() {scanf("%d%d%d", &n, &m1, &m2);g[0].scan(m1);g[1].scan(m2);bool f1 = g[0].judge(), f2 = g[1].judge();if(!f1 && !f2) {puts("SIMILAR") ;}else if(!f1 || !f2) {int k = 0;if(f2) k^=1;g[k].output();}else {g[0].getbit();g[1].getbit();if(gao(n, 0)) return 0;if(gao(0, n)) return 0;for(int i = 1; i <= n*2; ++i) {for(int j = 1; j <= n*2; ++j) {int u = g[0].sccno[i], v = g[0].sccno[j];int uu = g[1].sccno[i], vv = g[1].sccno[j];if(g[0].son[u][v] != g[1].son[uu][vv]) {int k = 0;if(g[0].son[u][v]) k = 1;g[k].add(i > n ? i-n : i + n, i);g[k].add(j, j > n ? j - n : j + n);g[k].find_scc();g[k].output();return 0;}}}puts("SIMILAR") ;}}
F Little Artem and Graph
题意:一开始1到k组成一个完全图,然后添加一个点i连接前面的k个点j(j < i ), 问生成树个数 (n <= 100000, k <= 5);
转叉姐的题解:
设 N(v)
表示点 v
的邻居,考虑 N(v)
中编号最大的点 u
,那么 N(v)⊂(N(u)∪{u})
.
把 v
作为 u
的儿子,得到一颗(有根)树。我们在树上进行 DP。
DP 的状态是 f(v,S)
,表示当决策完 v
这颗子树的点后,N(v)
里面点的连通性状态是 S
的方案数。
为了计算 f(v,S)
,我们转而计算 g(v,i,S)
表示决策完 v
的前 i
个儿子后,N(v)∪{v}
里面点的连通性状态是 S
的方案数。
考虑 g(v,0,S)
,唯一的方案就是考虑 v
和 N(v)
之间的边,一共有 2∣N(v)∣
种可能。当 i>0
时,其实就是枚举一个 g(v,i−1,S′)
和一个 f(ci,S′′)
进行合并。最后得到了 g(v,deg(v),S)
后,把 S
里面的点 v
去掉,就可以得到 f(v,S)
了。
再无耻的贴一个跑的最快的代码,好像就是生成树计数
#include <bits/stdc++.h>using namespace std;#define M 11111typedef long long ll;const ll mod = 1000000007;ll n, m;map<ll, ll> mp[M];vector<ll> v[M];ll POW(ll a, ll n) { ll s = 1; while (n) { if (n & 1) s = 1ll * s * a % mod; n >>= 1; a = 1ll * a * a % mod; } return s;}int main() { scanf("%d %d", &n, &m); if (m == 1) { puts("1"); return 0; } for (ll i = 1; i <= m; i++) for (ll j = 1; j <= m; j++) { if (i != j) { mp[i][j] = mp[j][i] = mod - 1; } else { mp[i][i] = m - 1; } if (i > j) { v[i].push_back(j); } } for (ll i = m + 1; i <= n; i++) { mp[i][i] = m; for (ll x, j = 1; j <= m; j++) { scanf("%I64d", &x); mp[i][x] = mod - 1; mp[x][i] = mod - 1; mp[x][x] ++; v[i].push_back(x); } } ll rlt = 1; for (ll i = n - 1; i >= 1; i--) { ll c = mp[i][i]; rlt = 1ll * rlt * c % mod; if (!c) { puts("0"); return 0; } c = POW(c, mod - 2); if (i == 1) { break; } for (ll j, r = 0; r < v[i].size(); r++) { j = v[i][r]; mp[i][j] = 1ll * c * mp[i][j] % mod; } for (ll j, r = 0; r < v[i].size(); r++) { j = v[i][r]; ll t = mp[j][i]; for (ll k, s = 0; s < v[i].size(); s++) { k = v[i][s]; ll w = mp[j][k]; w -= 1ll * mp[i][k] * t % mod; if (w < 0) w += mod; mp[j][k] = w; } } } printf("%I64d\n", rlt); return 0;}
- Codeforces Round #348 (VK Cup 2016 Round 2) E F (2-sat. 待补)
- [2-SAT] Codeforces 668E #348 (VK Cup 2016 Round 2, Div. 1 Edition) E. Little Artem and 2-SAT
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) E. Little Artem and Time Machine 树状数组
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) A B C D 模拟
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) D. Little Artem and Dance
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) D
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 1 Edition)
- Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) easy(上)
- Codeforces VK Cup 2016 - Round 1 (Div. 2 Edition)
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition)-A. Little Artem and Presents(模拟)
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition)-B. Little Artem and Grasshopper(模拟)
- Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) B.Problems for Round
- Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) B. Problems for Round
- Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) E. Levels and Regions(斜率优化dp) ★ ★ ★
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) F. Bamboo Partition
- VK Cup 2016 round 2题解
- VK Cup 2012 Round 2
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) E Cards Sorting
- window7 环境变量是JAVA JDK1.8和项目调用jre1.7多个版本问题
- 基于Spark的图计算框架 GraphX 入门介绍
- ubuntu 下 vpn python django mysqldb setupTool pip 等环境安装
- 【JSON】JSON在前端和后端传递
- 无法连接主机“192.168.30.7”: 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。
- Codeforces Round #348 (VK Cup 2016 Round 2) E F (2-sat. 待补)
- 六款值得推荐的android(安卓)开源框架简介
- Effective C++ 3e----new & delete(八)条款51:编写new和delete时需固守常规
- Xcode项目中的常见文件-UI进阶
- iOS之视频的三种播放方式
- leetcode.199. Binary Tree Right Side View
- 一个简单的Java命令行添加/删除联系人程序(仿C语言)
- 69个经典Spring面试题和答案
- POJ, 1379Run Away(模拟退火算法)