您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: