码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-01-22 07:00:06      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

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;
}


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

标签:

原文地址:http://blog.csdn.net/accelerator_/article/details/43009641

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!