CodeForces Gym 101615简要题解
2017-11-16 20:27
561 查看
Odd Palindrome
签到。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif string s; cin >> s; for (int i = 1; i < s.length(); i ++) if (s[i] == s[i - 1]) return puts("Or not."), 0; return puts("Odd."), 0; }
Enlarging Enthusiasm
f(s,p,c)表示当前状态为s,上一个人是p,当前还剩c的分数。每次枚举下一个人i,那么需要加的分是max(ap−ai+1,0),因为q单调,所以在这里直接减掉。
#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const int MAXN = 15; const int MAXM = 705; const int MAXS = 4100; int n, m, s, a[MAXN], f[MAXS][MAXN][MAXM]; inline int DFS(int s, int p, int c) { if (c < 0) return 0; if (s == (1 << n) - 1) return 1; if (~f[s][p][c]) return f[s][p][c]; f[s][p][c] = 0; for (int i = 0; i < n; i ++) if (!(s >> i & 1)) f[s][p][c] += DFS(s | 1 << i, i, c - max(a[p] - a[i] + 1, 0) * (n - __builtin_popcount(s))); return f[s][p][c]; } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif n = Read(), s = Read(); for (int i = 0; i < n; i ++) m = max(m, a[i] = Read()); mset(f, -1); int ans = 0; for (int i = 0; i < n; i ++) if (a[i] ^ m) ans += DFS(1 << i, i, s - (m - a[i] + 1) * n); return printf("%d\n", ans), 0; }
Fear Factoring
考虑每个约数贡献,下底函数分块之后等差数列求和。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } inline LL Solve(LL n) { LL ret = 0; for (LL l = 1, r; l <= n; l = r + 1) r = n / (n / l), ret += (l + r) * (r - l + 1) * (n / l); return ret; } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif LL a, b; scanf("%lld %lld", &a, &b); return printf("%lld\n", Solve(b) - Solve(a - 1) >> 1), 0; }
Rainbow Roads
枚举一个点,如果跟他相连的有两条相邻颜色的边,那么这两个子树都不是好的,求出DFS序之后打差分标记。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const int MAXN = 50005; int n, tim, seq[MAXN], dfn[MAXN], siz[MAXN], par[MAXN], sum[MAXN]; vector <pii> adj[MAXN]; inline void DFS(int x) { siz[x] = 1, seq[dfn[x] = ++ tim] = x; for (auto e : adj[x]) if (e.yy ^ par[x]) par[e.yy] = x, DFS(e.yy), siz[x] += siz[e.yy]; } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif n = Read(); for (int i = 1, x, y, w; i < n; i ++) x = Read(), y = Read(), w = Read(), adj[x].pb(mp(w, y)), adj[y].pb(mp(w, x)); DFS(1); for (int i = 1; i <= n; i ++) { sort(adj[i].begin(), adj[i].end()); for (int l = 0, r = 0; l < adj[i].size(); l = r) { while (r < adj[i].size() && adj[i][r].xx == adj[i][l].xx) r ++; if (r - l ^ 1) { for (int j = l; j < r; j ++) if (adj[i][j].yy == par[i]) sum[1] ++, sum[dfn[i]] --, sum[dfn[i] + siz[i]] ++; else sum[dfn[adj[i][j].yy]] ++, sum[dfn[adj[i][j].yy] + siz[adj[i][j].yy]] --; } } } vector <int> ans; for (int i = 1; i <= n; i ++) if (!(sum[i] += sum[i - 1])) ans.pb(seq[i]); printf("%d\n", ans.size()); sort(ans.begin(), ans.end()); for (auto x : ans) printf("%d\n", x); return 0; }
Straight Shot
二分水平速度。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const int MAXN = 105; const double eps = 1e-9; int n, x, l[MAXN], r[MAXN]; double v, w[MAXN]; inline double Chk(double mid) { double d = sqrt(v * v - mid * mid), ret = -x / mid * d; for (int i = 1; i <= n; i ++) ret += (r[i] - l[i]) / mid * w[i]; return ret; } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif n = Read(), x = Read(), scanf("%lf", &v); double delta = 0; for (int i = 1; i <= n; i ++) l[i] = Read(), r[i] = Read(), scanf("%lf", &w[i]), delta += (r[i] - l[i]) / v * w[i]; if (fabs(delta) < eps) return printf("%.3lf\n", x / v), 0; if (delta < 0) for (int i = 1; i <= n; i ++) w[i] = -w[i]; double l = v / 2, r = v; for (int i = 1; i <= 100; i ++) { double mid = (l + r) / 2; if (Chk(mid) < 0) l = mid; else r = mid; } if (fabs(Chk(l)) < eps) return printf("%.3lf\n", x / l), 0; return puts("Too hard"), 0; }
Distinct Distances
答案是两个点中点或者两条垂直平分线交点。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const double eps = 1e-9; inline int Sgn(double x) { return fabs(x) < eps ? 0 : x > 0 ? 1 : -1; } inline int Cmp(double x, double y) { return Sgn(x - y); } inline bool Mid(double l, double r, double mid) { return Cmp(l, mid) * Cmp(r, mid) <= 0; } struct Point { double x, y; Point(double _x = 0, double _y = 0) { x = _x, y = _y; } Point operator + (const Point &b) const { return Point(x + b.x, y + b.y); } Point operator - (const Point &b) const { return Point(x - b.x, y - b.y); } Point operator * (const double &b) const { return Point(x * b, y * b); } Point operator / (const double &b) const { return Point(x / b, y / b); } double operator * (const Point &b) const { return x * b.x + y * b.y; } double operator ^ (const Point &b) const { return x * b.y - y * b.x; } bool operator == (const Point &b) const { return !Cmp(x, b.x) && !Cmp(y, b.y); } bool operator != (const Point &b) const { return Cmp(x, b.x) || Cmp(y, b.y); } inline double Len() { return x * x + y * y; } }; inline double Dis(Point x, Point y) { return sqrt((x - y).Len()); } inline bool Mid(Point l, Point r, Point mid) { return Mid(l.x, r.x, mid.x) && Mid(l.y, r.y, mid.y); } inline bool Intersect_Line(Point l1, Point r1, Point l2, Point r2) { return Cmp((l2 - l1) ^ (r2 - l1), (l2 - r1) ^ (r2 - r1)); } inline Point Get_Intersect(Point l1, Point r1, Point l2, Point r2) { double w1 = (l1 - l2) ^ (r2 - l2), w2 = (r2 - l2) ^ (r1 - l2); return (l1 * w2 + r1 * w1) / (w1 + w2); } const int MAXN = 45; int n, ans; double d[MAXN]; Point a[MAXN]; inline void Solve(Point p) { for (int i = 1; i <= n; i ++) d[i] = Dis(a[i], p); sort(d + 1, d + n + 1); int ret = 1; for (int i = 2; i <= n; i ++) ret += Cmp(d[i], d[i - 1]); ans = min(ans, ret); } inline pair <Point, Point> Get(Point a, Point b) { Point c = (a + b) / 2, d = b - a; return mp(c, Point(c.x - d.y, c.y + d.x)); } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif n = ans = Read(); for (int i = 1; i <= n; i ++) a[i].x = Read(), a[i].y = Read(); for (int i = 1; i <= n; i ++) for (int j = 1; j <= n; j ++) Solve((a[i] + a[j]) / 2); for (int i = 1; i <= n; i ++) for (int j = 1; j < i; j ++) for (int k = 1; k <= n; k ++) for (int l = 1; l < k; l ++) { auto p = Get(a[i], a[j]).xx, q = Get(a[i], a[j]).yy, r = Get(a[k], a[l]).xx, s = Get(a[k], a[l]).yy; if (Intersect_Line(p, q, r, s)) Solve(Get_Intersect(p, q, r, s)); } return printf("%d\n", ans), 0; }
Security Badge
离散化之后暴力BFS。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const int MAXN = 1005; const int MAXM = 10005; int n, m, c, k, s, t, ans, l[MAXM]; vector <pair <int, pii>> adj[MAXN]; bool vis[MAXN]; inline void DFS(int x, int v) { vis[x] = 1; for (auto e : adj[x]) if (v >= e.yy.xx && v <= e.yy.yy && !vis[e.xx]) DFS(e.xx, v); } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif n = Read(), m = Read(), l[++ c] = k = Read(), s = Read(), t = Read(); for (int i = 1, x, y, w, v; i <= m; i ++) x = Read(), y = Read(), w = Read(), v = Read(), l[++ c] = w - 1, l[++ c] = v, adj[x].pb(mp(y, mp(w, v))); sort(l + 1, l + c + 1), c = unique(l + 1, l + c + 1) - l - 1; for (int i = 1; i <= c; i ++) { for (int j = 1; j <= n; j ++) vis[j] = false; DFS(s, l[i]); if (vis[t]) ans += l[i] - l[i - 1]; if (l[i] == k) return printf("%d\n", ans), 0; } return 0; }
Avoiding Airports
扫描线维护时间,fe表示最后一次是e这条边的最小代价,斜率优化。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const int MAXN = 200005; const LL INF = 1LL << 60; int n, m, d[MAXN], u[MAXN], v[MAXN], w[MAXN], z[MAXN], ql[MAXN], qr[MAXN]; vector <pair <int, LL>> vec[MAXN]; vector <int> eve[MAXN * 5]; LL f[MAXN]; inline void Insert(int p, int x, LL y) { if (y >= INF) return ; if (ql[p] <= qr[p] && vec[p][qr[p]].xx == x) { if (vec[p][qr[p]].yy <= y) return ; qr[p] --; } while (ql[p] < qr[p] && (vec[p][qr[p]].xx - vec[p][qr[p] - 1].xx) * (y - vec[p][qr[p]].yy) <= (x - vec[p][qr[p]].xx) * (vec[p][qr[p]].yy - vec[p][qr[p] - 1].yy)) qr[p] --; vec[p][++ qr[p]] = mp(x, y); } inline LL Query(int p, int k) { if (ql[p] > qr[p]) return INF; while (ql[p] < qr[p] && vec[p][ql[p]].yy - 1LL * k * vec[p][ql[p]].xx >= vec[p][ql[p] + 1].yy - 1LL * k * vec[p][ql[p] + 1].xx) ql[p] ++; return vec[p][ql[p]].yy - 1LL * k * vec[p][ql[p]].xx; } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif n = Read(), m = Read(), d[1] = 1; for (int i = 1; i <= m; i ++) u[i] = Read(), v[i] = Read(), w[i] = Read(), z[i] = Read(), d[v[i]] ++, eve[w[i]].pb(-i), eve[z[i]].pb(i); for (int i = 1; i <= n; i ++) vec[i].resize(d[i] + 1), qr[i] = -1; Insert(1, 0, 0); for (int i = 0; i <= 1000000; i ++) for (auto x : eve[i]) if (x < 0) { x = -x; f[x] = Query(u[x], w[x]); if (f[x] < INF) f[x] += 1LL * w[x] * w[x]; } else Insert(v[x], z[x] << 1, 1LL * z[x] * z[x] + f[x]); LL ans = INF; for (int i = 1; i <= m; i ++) if (v[i] == n) ans = min(ans, f[i]); return printf("%lld\n", ans), 0; }
Long Long Strings
初始弄一个从26开始的无穷递增数列,用set压缩区间,暴力维护。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline LL Read() { LL x = 0; int f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const LL INF = 1LL << 40; struct Node { LL l, r, v; Node(LL _l = 0, LL _r = 0, LL _v = 0) { l = _l, r = _r, v = _v; } bool operator < (const Node &b) const { return l < b.l || (l == b.l && r < b.r) || (l == b.l && r == b.r && v < b.v); } }; set <Node> s1, s2; inline void Solve(set <Node> &s) { s.insert(Node(0, INF, 26)); char opt[10]; while (true) { scanf("%s", opt); if (opt[0] == 'D') { LL x = Read(), l, r, v; auto it = -- s.upper_bound(Node(x + 1, 0, 0)), jt = it; l = it -> l, r = it -> r, v = it -> v, jt ++, s.erase(it); vector <Node> vec; if (l ^ x) vec.pb(Node(l, x - 1, v)); if (x ^ r) vec.pb(Node(x, r - 1, v - l + x + 1)); while (jt != s.end()) l = jt -> l, r = jt -> r, v = jt -> v, s.erase(jt ++), vec.pb(Node(l - 1, r - 1, v)); for (auto x : vec) s.insert(x); } else if (opt[0] == 'I') { LL x = Read() - 1, l, r, v, t; scanf("%s", opt), t = opt[0] - 'A'; auto it = -- s.upper_bound(Node(x + 1, 0, 0)), jt = it; l = it -> l, r = it -> r, v = it -> v, jt ++, s.erase(it); vector <Node> vec; vec.pb(Node(l, x, v)); if (x ^ r) vec.pb(Node(x + 2, r + 1, v - l + x + 1)); vec.pb(Node(x + 1, x + 1, t)); while (jt != s.end()) l = jt -> l, r = jt -> r, v = jt -> v, s.erase(jt ++), vec.pb(Node(l + 1, r + 1, v)); for (auto x : vec) s.insert(x); } else break; } } inline bool Chk(set <Node> a, set <Node> b) { while (!a.empty() || !b.empty()) { if (a.empty() || b.empty()) return true; auto it = a.begin(), jt = b.begin(); if (it -> l != jt -> l || it -> v != jt -> v) return true; if (it -> r == jt -> r) a.erase(it), b.erase(jt); else if (it -> r < jt -> r) b.insert(Node(it -> r + 1, jt -> r, jt -> v - it -> l + it -> r + 1)), a.erase(it), b.erase(jt); else a.insert(Node(jt -> r + 1, it -> r, it -> v - jt -> l + jt -> r + 1)), a.erase(it), b.erase(jt); } return false; } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif Solve(s1), Solve(s2); return printf("%d\n", Chk(s1, s2)), 0; }
Grid Coloring
f(i,j)表示前i行,最后一个B是j的方案数。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const int MAXN = 35; int n, m, l[MAXN], r[MAXN]; LL f[MAXN][MAXN]; char s[MAXN]; int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif n = Read(), m = Read(); for (int i = 1; i <= n; i ++) { scanf("%s", s + 1); int p = 0; for (int j = 1; j <= m; j ++) if (s[j] == 'B') p = j; if (!p) { l[i] = 0; for (int j = 1; j <= m; j ++) if (s[j] == 'R') r[i] = j - 1, j = m + 1; else if (j == m) r[i] = m; } else { for (int j = 1; j <= p; j ++) if (s[j] == 'R') return puts("0"), 0; l[i] = p; for (int j = p; j <= m; j ++) if (s[j] == 'R') r[i] = j - 1, j = m + 1; else r[i] = m; } } f[0][m] = 1; for (int i = 0; i < n; i ++) for (int j = 0; j <= m; j ++) if (f[i][j]) for (int k = l[i + 1]; k <= r[i + 1] && k <= j; k ++) f[i + 1][k] += f[i][j]; LL ret = 0; for (int i = 0; i <= m; i ++) ret += f [i]; return printf("%lld\n", ret), 0; }
Spinning Up Palindromes
从两边往中间DP,f(i,0/1,0/1)表示前i位,是否需要进位,后几位是否进位的最小代价。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const int MAXN = 45; const int INF = 0x3f3f3f3f; int n, ans = INF, a[MAXN], f[MAXN][2][2]; char s[MAXN]; int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif scanf("%s", s + 1), n = strlen(s + 1); for (int i = 1; i <= n; i ++) a[i] = s[i] - '0'; mset(f, 0x3f), f[0][1][0] = f[0][0][0] = 0; for (int l = 1, r = n; l < r; l ++, r --) for (int i = 0; i < 2; i ++) for (int j = 0; j < 2; j ++) if (f[l - 1][i][j] ^ INF) for (int k = 0; k < 2; k ++) for (int x = 0; x < 10; x ++) for (int y = 0; y < 10; y ++) { int u = a[l] + x + k, v = a[r] + y + j, m = v > 9; if ((u > 9) ^ i) continue; if (u > 9) u -= 10; if (v > 9) v -= 10; if (u == v) f[l][k][m] = min(f[l][k][m], f[l - 1][i][j] + x + y); } if (!(n & 1)) for (int i = 0; i < 2; i ++) ans = min(ans, f[n >> 1][i][i]); else for (int i = 0; i < 2; i ++) for (int j = 0; j < 2; j ++) for (int x = 0; x < 10; x ++) if ((a[n + 1 >> 1] + x + j) / 10 == i) ans = min(ans, f[n >> 1][i][j] + x); return printf("%d\n", ans), 0; }
Delayed Work
暴力。#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif int k = Read(), p = Read(), x = Read(); double ans = 1e9; for (int i = 1; i <= 10000; i ++) ans = min(ans, (double)k * p / i + x * i); return printf("%.3lf\n", ans), 0; }
Unsatisfying
如果没有¬i∨¬j的限制,那么显然无解。如果原来2-SAT就无解那么显然无解了,不然最优解一定是加i∨i这种形式,显然答案不超过2,枚举每个点,判断答案是否为1就行了。
#include <bits/stdc++.h> #define xx first #define yy second #define mp make_pair #define pb push_back #define mset(x, y) memset(x, y, sizeof x) #define mcpy(x, y) memcpy(x, y, sizeof x) using namespace std; typedef long long LL; typedef pair <int, int> pii; inline int Read() { int x = 0, f = 1, c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f; } const int MAXN = 4005; int n, m, tim, top, cnt, sta[MAXN], dfn[MAXN], low[MAXN], scc[MAXN]; vector <int> adj[MAXN], adv[MAXN]; inline void DFS(int x) { sta[++ top] = x, dfn[x] = low[x] = ++ tim; for (auto y : adj[x]) if (!dfn[y]) DFS(y), low[x] = min(low[x], low[y]); else if (!scc[y]) low[x] = min(low[x], dfn[y]); if (low[x] == dfn[x]) { int k = 0; for (cnt ++; k ^ x; scc[k = sta[top --]] = cnt); } } int main() { #ifdef wxh010910 freopen("data.in", "r", stdin); #endif n = Read(), m = Read(); bool flg = false; for (int i = 1; i <= m; i ++) { int x = Read(), y = Read(); flg |= x < 0 && y < 0; if (x < 0) x = n - x; if (y < 0) y = n - y; if (x <= n) adv[x + n].pb(y); else adv[x - n].pb(y); if (y <= n) adv[y + n].pb(x); else adv[y - n].pb(x); } if (!flg) return puts("-1"), 0; for (int i = 1; i <= n << 1; i ++) for (auto j : adv[i]) adj[i].pb(j); for (int i = 1; i <= n << 1; i ++) if (!dfn[i]) DFS(i); for (int i = 1; i <= n; i ++) if (scc[i] == scc[i + n]) return puts("0"), 0; for (int i = 1; i <= n; i ++) { for (int j = 1; j <= n << 1; j ++) adj[j].clear(), dfn[j] = low[j] = scc[j] = 0; tim = cnt = 0; for (int j = 1; j <= n << 1; j ++) for (auto k : adv[j]) adj[j].pb(k); adj[i + n].pb(i); for (int j = 1; j <= n << 1; j ++) if (!dfn[j]) DFS(j); for (int j = 1; j <= n; j ++) if (scc[j] == scc[j + n]) return puts("1"), 0; } return puts("2"), 0; }
相关文章推荐
- CodeForces Gym 101741 简要题解
- CodeForces Gym 101630简要题解
- CodeForces Gym 101190简要题解
- CodeForces Gym 101620简要题解
- [Codeforces Gym]2015年ACM-ICPC越南国赛第二场简要题解
- CodeForces Gym 101745 简要题解
- Codeforces gym 100685 A. Ariel 暴力
- Codeforces Gym 101608 G WiFi Password(尺取/二分+ST表 )
- codeforces Gym 100286H Hell on the Markets
- codeforces gym 100357 J (网络流)
- Codeforces gym 101102 D 单调栈
- Codeforces Gym 100650D Queens, Knights and Pawns 暴力
- CodeForces Gym 100989B LCS (B)
- Codeforces Gym 100338H High Speed Trains 组合数学+dp+高精度
- CodeForcesGym 100676G Training Camp
- codeforces Gym 101341 K Competitions
- codeforces Gym 100269K——Kids in a Friendly Class(可图性判定)
- CodeForces Gym 100646C LCR
- codeforces gym 100345I Segment Transformations [想法题]
- Codeforces Gym 100002 D"Decoding Task" 数学