Codeforces Round #286 (Div. 1) C、D

C:题目中步数看似很多,其实最多就增长250步左右,因为移动的步数为1 + 2 + 3 + .. n,所以大概只会有sqrt(n)步,所以dp[i][j]表示在i位置,增长为j步的值,然后转移即可

D:这题其实对于一个联通块,最多只需要n条边,最少要n - 1条,那么判断的条件,就是这个联通块是否有环,利用拓扑排序去判即可

代码:

C:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 30005;

int n, d, cnt[N], dp[N][500];

int dfs(int u, int cha) {
    if (u > 30000) return 0;
    if (dp[u][cha] != -1) return dp[u][cha];
    int tmp = d + cha - 250;
    dp[u][cha] = cnt[u];
    int ans = 0;
    if (tmp > 1)
	ans = max(ans, dfs(u + tmp - 1, cha - 1));
    ans = max(ans, dfs(u + tmp, cha));
    ans = max(ans, dfs(u + tmp + 1, cha + 1));
    dp[u][cha] += ans;
    return dp[u][cha];
}

int main() {
    scanf("%d%d", &n, &d);
    int tmp;
    for (int i = 0; i < n; i++) {
	scanf("%d", &tmp);
	cnt[tmp]++;
    }
    memset(dp, -1, sizeof(dp));
    printf("%d\n", dfs(d, 250));
    return 0;
}

D:

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

const int N = 100005;

int n, m, du[N], vis[N], have[N], hn;
vector<int> g[N], g2[N];

void dfs(int u) {
    have[hn++] = u;
    vis[u] = 1;
    for (int i = 0; i < g[u].size(); i++) {
        int v = g[u][i];
        if (vis[v]) continue;
        dfs(v);
    }
}

bool find() {
    queue<int> Q;
    for (int i = 0; i < hn; i++)
        if (!du[have[i]]) Q.push(have[i]);
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();
        int sz = g2[u].size();
        for (int i = 0; i < sz; i++) {
            int v = g2[u][i];
            du[v]--;
            if (!du[v]) Q.push(v);
        }
    }
    for (int i = 0; i < hn; i++)
        if (du[have[i]]) return true;
    return false;
}

int main() {
    scanf("%d%d", &n, &m);
    int u, v;
    while (m--) {
        scanf("%d%d", &u, &v);
        du[v]++;
        g[u].push_back(v);
        g[v].push_back(u);
        g2[u].push_back(v);
    }
    int ans = n;
    for (int i = 1; i <= n; i++) {
        if (!vis[i]) {
            hn = 0;
            dfs(i);
            if (!find()) ans--;
        }
    }
    printf("%d\n", ans);
    return 0;
}
时间: 2024-07-30 10:09:01

Codeforces Round #286 (Div. 1) C、D的相关文章

Codeforces Round #286 div.1 D 506D D. Mr. Kitayuta&#39;s Colorful Graph【并查集】

题目链接:http://codeforces.com/problemset/problem/506/D 题目大意: 给出n个顶点,m条边,每条边上有一个数字,代表某个颜色.不同数字代表不同的颜色.有很多个询问,每个询问问有多少条纯种颜色的路径使得某两个点联通. 分析: 这个题一看就想用并查集来搞,每种颜色用一个并查集处理.对于输入的每条边,我们只需要将这两个点在这条边的颜色对应的并查集中合并就好了.查询的时候,我们只需要检测这两个点在多少个颜色对应的并查集中是在统一集合中的,那么就有多少条纯种颜

Codeforces Round #250 (Div. 2) C、The Child and Toy

注意此题,每一个部分都有一个能量值v[i],他移除第i部分所需的能量是v[f[1]]+v[f[2]]+...+v[f[k]],其中f[1],f[2],...,f[k]是与i直接相连(且还未被移除)的部分的编号. 注意题目移除的都是与第i部分直接相连的部分的能量值, 将本题目简化得,只考虑两个点1和2,1和2相连,1的能量值是10,2的能量值是20, 移除绳子时,要保持能量最小,可以移除部分2,这样移除的能量就是与2相连的部分1的能量即是10: 故每次相连两部分都移除能量值大的即可 #includ

Codeforces Round #286 (Div. 2)B. Mr. Kitayuta&#39;s Colorful Graph(dfs,暴力)

数据规模小,所以就暴力枚举每一种颜色的边就行了. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm>

Codeforces Round #286 div.2 D 505D. Mr. Kitayuta&#39;s Technology【强连通分量,弱联通分量】

题目链接:http://codeforces.com/contest/505/problem/D 题目大意: 在一个图中,有n个顶点,给出m对数字(u,v)表示顶点u和顶点v必须直接或者间接相连,让你构造一个这样的图,输出最少需要多少条边. 分析: 毫无疑问,n个顶点的话,我们最多可以用n条边,使得n个顶点构成一个环,满足所有的情况(任意两点都是联通的),但是这并不一定是最少的边. 于是我们还需要找一个方法确定最少需要多少条边. 首先我们利用题目给出的点对建图,得到图G.对于G中的弱联通分量来说

Codeforces Round #286 (Div. 2)A. Mr. Kitayuta&#39;s Gift(暴力,string的应用)

由于字符串的长度很短,所以就暴力枚举每一个空每一个字母,出现行的就输出.这么简单的思路我居然没想到,临场想了很多,以为有什么技巧,越想越迷...是思维方式有问题,遇到问题先分析最简单粗暴的办法,然后一步一步的优化,不能盲目的想. 这道题要AC的快需要熟悉string的各种用法.这里做个简单总结:C++中string的常见用法. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstrin

Codeforces Round #251 (Div. 2) C、D

Codeforces Round #251 (Div. 2) C题: 题意:给定一些数字,要把这些数字方程k行,其中p行和为奇数,剩下和为偶数. 思路:根据奇数偶数的性质,先把p行放1个奇数,然后看看剩下的奇数是不是偶数个,如果不是肯定不满足,然后判断一下剩下的奇数个数/2加上偶数个数是否多余p个,如果不是肯定不满足,然后把这些放入p行,还有剩下的数字就全丢到最后一行去. D题: 题意:给定两个序列,每次操作可以对序列中的数字进行+1或者-1,要使得a序列的最小大于b序列的最大,问最少需要几次操

Codeforces Round #286 (Div. 2) B. Mr. Kitayuta&#39;s Colorful Graph +foyd算法的应用

B. Mr. Kitayuta's Colorful Graph time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Mr. Kitayuta has just bought an undirected graph consisting of n vertices and m edges. The vertices of the g

水题 Codeforces Round #286 (Div. 2) A Mr. Kitayuta&#39;s Gift

题目传送门 1 /* 2 水题:vector容器实现插入操作,暴力进行判断是否为回文串 3 */ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <cstring> 8 #include <string> 9 #include <vector> 10 using namespace std; 11 12 const int MAXN

DFS/并查集 Codeforces Round #286 (Div. 2) B - Mr. Kitayuta&#39;s Colorful Graph

题目传送门 1 /* 2 题意:两点之间有不同颜色的线连通,问两点间单一颜色连通的路径有几条 3 DFS:暴力每个颜色,以u走到v为结束标志,累加条数 4 注意:无向图 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <string> 11 #include <vector> 1