Codeforces Round #286 (Div. 1) 解题报告
A.Mr. Kitayuta, the Treasure Hunter
很显然的一个DP,30000的数据导致使用map+set会超时。题解给了一个非常实用的做法,由于每个点有不超过250种状态,并且这些状态都是以包含d连续的一段数字,那么可以以对d的偏移量作为状态。这算是很常见的一个优化了。
#include<bits/stdc++.h>
using namespace std;
const int INF = ;
int f[INF][],a[INF];
int n, d, ans = , x;
int main() {
scanf ("%d %d", &n, &d);
for (int i = ; i <= n; i++) {
scanf ("%d", &x);
a[x]++;
}
f[d][] = a[d] + ;
for (int i = d; i <= x; i++)
for (int j = ; j < ; j++) {
if (f[i][j] == ) continue;
int k = j - + d, val = f[i][j];
ans = max (ans, val);
for (int t = max (, k - ); t <= k + ; t++)
if (i + t <= x)
f[i + t][t - d + ] = max (f[i + t][t - d + ], val + a[i + t]);
}
printf ("%d\n", ans - );
}
[Problem] Given an integer n and m pairs of integers (ai, bi) (1 ≤ ai, bi ≤ n), find the minimum number of edges in a directed graph that satisfies the following condition:
- For each i, there exists a path from vertex ai to vertex bi.
对于一个n个点的强连通图最少需要n条边,而非强连通的n个有边连接的点最少需要n-1条边。那么只要判断连通起来的k个点组成的块是不是有环,如果有环需要k条边,无环需要k-1条边。在连完一个连通的块后将其合并看成一个点。直到所有点都遍历过。
#include<bits/stdc++.h>
using namespace std;
const int INF = ;
struct Edge {
int v, next;
} edge[INF];
int head[INF], ncnt ;
int f[INF], vis[INF], cycle[INF], siz[INF];
int n, m, ans;
inline void adde (int u, int v) {
edge[++ncnt].v = v, edge[ncnt].next = head[u];
head[u] = ncnt;
}
inline int find (int x) {
if (f[x] == x) return x;
return f[x] = find (f[x]);
}
inline void uin (int x, int y)
{
siz[find (x)] += siz[find (y)];
f[find (y)] = find (x);
}
inline bool dfs (int u) {
vis[u] = ;
for (int i = head[u]; i; i = edge[i].next) {
int v = edge[i].v;
if (!vis[v]) dfs (v);
if (vis[v] == ) cycle[find (u)] = ;
}
vis[u] = ;
}
int main() {
scanf ("%d %d", &n, &m);
for (int i = ; i <= n; i++) f[i] = i, siz[i] = ;
for (int i = , x, y; i <= m; i++) {
scanf ("%d %d", &x, &y);
adde (x, y);
if (find (x) != find (y) ) uin (x, y);
}
for (int i = ; i <= n; i++)
if (!vis[i]) dfs (i);
for (int i = ; i <= n; i++) {
if (find (i) == i)
ans += siz[i] - ;
ans += cycle[i];
}
printf ("%d\n", ans);
}
D.Mr. Kitayuta's Colorful Graph
题意:一个n个点m条边的无向图中所有的边都有一个颜色,有q个询问,对每个询问(u,v)输出从u到v的纯色路径条数。(n,m,q<1e5)
首先应该先把所有相同颜色边连接的块做一次并查集,然后对所有询问(a,b)对a,b中有着较少的度的点的颜色查找b是否与a在一个集合。
unordered_map能够在让查找b的时间降到O(1)
#include<bits/stdc++.h>
using namespace std;
const int INF = ; unordered_map<int, int> f[INF], old[INF]; int n, m, q;
inline int find (int x, int c) {
if (f[x][c] < ) return x;
return f[x][c] = find (f[x][c], c);
}
inline void merge (int x, int y, int c) {
if (f[x].find (c) == f[x].end() ) f[x][c] = -;
if (f[y].find (c) == f[y].end() ) f[y][c] = -;
x = find (x, c), y = find (y, c);
if (x == y) return;
f[y][c] += f[x][c];
f[x][c] = y;
}
int main() {
scanf ("%d %d", &n, &m);
for (int i = , x, y, c; i <= m; i++) {
scanf ("%d %d %d", &x, &y, &c);
merge (x, y, c);
}
scanf ("%d", &q);
int a, b;
while (q--) {
scanf ("%d %d", &a, &b);
if (f[a].size() > f[b].size() ) swap (a, b);
if (old[a].find (b) == old[a].end() ) {
int ans = ;
for (auto &c : f[a])
if (f[b].find (c.first) != f[b].end() && find (a, c.first) == find (b, c.first) )
ans++;
old[a][b] = ans;
}
printf ("%d\n", old[a][b]);
}
}
Codeforces Round #286 (Div. 1) 解题报告的更多相关文章
- Codeforces Round #324 (Div. 2)解题报告
---恢复内容开始--- Codeforces Round #324 (Div. 2) Problem A 题目大意:给二个数n.t,求一个n位数能够被t整除,存在多组解时输出任意一组,不存在时输出“ ...
- Codeforces Round #382 (Div. 2) 解题报告
CF一如既往在深夜举行,我也一如既往在周三上午的C++课上进行了virtual participation.这次div2的题目除了E题都水的一塌糊涂,参赛时的E题最后也没有几个参赛者AC,排名又成为了 ...
- Codeforces Round #380 (Div. 2) 解题报告
第一次全程参加的CF比赛(虽然过了D题之后就开始干别的去了),人生第一次codeforces上分--(或许之前的比赛如果都参加全程也不会那么惨吧),终于回到了specialist的行列,感动~.虽然最 ...
- Codeforces Round #216 (Div. 2)解题报告
又范低级错误! 只做了两题!一道还被HACK了,囧! A:看了很久!应该是到语文题: 代码:#include<iostream> #include<]; ,m2=; ;i ...
- Codeforces Round #281 (Div. 2) 解题报告
题目地址:http://codeforces.com/contest/493 A题 写完后就交了,然后WA了,又读了一遍题,没找出错误后就开始搞B题了,后来回头重做的时候才发现,球员被红牌罚下场后还可 ...
- Codeforces Round #277 (Div. 2) 解题报告
题目地址:http://codeforces.com/contest/486 A题.Calculating Function 奇偶性判断,简单推导公式. #include<cstdio> ...
- Codeforces Round #276 (Div. 2) 解题报告
题目地址:http://codeforces.com/contest/485 A题.Factory 模拟.判断是否出现循环,如果出现,肯定不可能. 代码: #include<cstdio> ...
- Codeforces Round #350 (Div. 2)解题报告
codeforces 670A. Holidays 题目链接: http://codeforces.com/contest/670/problem/A 题意: A. Holidays On the p ...
- Codeforces Round #479 (Div. 3)解题报告
题目链接: http://codeforces.com/contest/977 A. Wrong Subtraction 题意 给定一个数x,求n次操作输出.操作规则:10的倍数则除10,否则减1 直 ...
随机推荐
- 【转】怎么在Foxmail回复/转发时使用签名?
原文网址:http://kf.qq.com/faq/120322fu63YV130422yABZRZ.html Foxmail回复/转发时使用签名,可通过在模版中设置签名.如下版本操作方法: 一.fo ...
- HDU --- 4006
The kth great number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Oth ...
- 《Linear Algebra and Its Applications》-chaper6-正交性和最小二乘法- 格拉姆-施密特方法
构造R^n子空间W一组正交基的算法:格拉姆-施密特方法.
- 《A First Course in Probability》-chaper2-概率论公理
概率论自身有一套很深的理论体系,读过<几何原本>的读者会知道,伟大的欧几里得之所以伟大,是因为它基于几条最基本的公理,推导除了整个欧式几何学的理论体系,同样,在概率论这里,一切的推导都是源 ...
- 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数
找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数 #include<iostream>using namespace s ...
- 编译android的linux kernel goldfish
https://source.android.com/source/building-kernels.html $ export PATH=/home/hzh/oldhome/learn/androi ...
- MongoDB Java 连接配置
[前言] 由于处于线程安全等考虑,MongoDBJava从3.0开始已经打算废弃DB开头的类的使用,所以整体调用上有了较大的区别,特以此文志之 [正文] 环境配置 在Java程序中如果要使用Mongo ...
- hdu5127 Dogs' Candies CDQ分治 动态凸包
传送门 题意 有三种操作 加入一个二元组\((x,y)\) 删除一个二元组\((x,y)\) 给出一个二元组\((a,b)\),问\(ax+by\)的最大值 题解 \(z=ax+by \Rightar ...
- PHP运行出现Notice : Use of undefined constant 的解决方法【已测】
关闭 PHP 提示的方法 搜索php.ini:error_reporting = E_ALL改为:error_reporting = E_ALL & ~E_NOTICE还有个不是办法的办法就是 ...
- 微软ASP.NET网站部署指南(10):迁移至SQL Server
1. 综述 第2章的部署SQL Server Compact和第9章的部署数据库更新里解释了为什么终于要升级到完整版SQL Server .本章节将告诉你怎样来做. SQL Server Expre ...