您的位置:首页 > 其它

单挑养成计划【2】 AtCoder Grand Contest 005

2016-10-26 19:54 447 查看

ABC

我懒得写了。。(啪

D - ~K Perm Counting

题意:求有多少种1~N的全排列,不存在位置i,使得i上的数ai满足 |ai - i| = K。

题解:一眼容斥。思考怎么算有i个不合法位置的方案数Mi。考虑转化成一个二分图,左边N个数代表位置,右边N个数代表数字。在图上建边跑DP。有很多种姿势的DP啊非常迷……边边点点的搞一搞(

1 #include <cstdio>
2 #include <cstdlib>
3 #include <cstring>
4 #include <algorithm>
5 #include <iostream>
6 #include <vector>
7 #include <queue>
8 using namespace std;
9 const int maxn = 2e6 + 5;
10 vector<int> blue[maxn], red[maxn];
11 int dep[maxn], fa[maxn], dp[maxn];
12 bool safe[maxn], vis[maxn];
13 void dfs(int v, int p) {
14     fa[v] = p;
15     for (int i=0; i<blue[v].size(); i++) if(blue[v][i] != p) {
16         dep[blue[v][i]] = dep[v] + 1;
17         dfs(blue[v][i], v);
18     }
19 }
20 bool atMost2(int x, int y) {
21     return (fa[x] == fa[y]) || (fa[x] == y) || (x == fa[y]) || (fa[fa[x]] == y) || (x == fa[fa[y]]);
22 }
23 int main() {
24     int n, X, Y, x, y;
25     scanf("%d %d %d", &n, &X, &Y);
26     for (int i=1; i<n; i++) {
27         scanf("%d %d", &x, &y);
28         red[x].push_back(y), red[y].push_back(x);
29     }
30     for (int i=1; i<n; i++) {
31         scanf("%d %d", &x, &y);
32         blue[x].push_back(y), blue[y].push_back(x);
33     }
34     dfs(Y, -1);
35     for (int i=1; i<=n; i++)
36         for (int j=0; j<red[i].size(); j++)
37             if (!atMost2(i, red[i][j]))
38                 safe[i] = safe[red[i][j]] = 1;
39     if (safe[X]) {puts("-1"); return 0;}
40     memset(dp, -1, sizeof(dp));
41     queue<int> q;
42     q.push(X); dp[X] = 0; vis[X] = 0;
43     int ans = 0;
44     while (!q.empty()) {
45         int u = q.front(); q.pop();
46         if (dp[u] >= dep[u]) continue;
47         if (safe[u]) {puts("-1"); return 0;}
48         ans = max(ans, dep[u] * 2);
49         for (int i=0; i<red[u].size(); i++) {
50             int v = red[u][i];
51             if (!vis[v] && dp[u] + 1 < dep[v] && atMost2(u, v)) {
52                 dp[v] = dp[u] + 1;
53                 vis[v] = 1;
54                 q.push(v);
55             }
56         }
57     }
58     printf("%d\n", ans);
59     return 0;
60 }


View Code

F。。等我学会了FFT再说吧(
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: