zoukankan      html  css  js  c++  java
  • 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 = 30009;
    int f[INF][500],a[INF];
    int n, d, ans = 1, x;
    int main() {
        scanf ("%d %d", &n, &d);
        for (int i = 1; i <= n; i++) {
            scanf ("%d", &x);
            a[x]++;
        }
        f[d][250] = a[d] + 1;
        for (int i = d; i <= x; i++)
            for (int j = 0; j < 500; j++) {
                if (f[i][j] == 0) continue;
                int k = j - 250 + d, val = f[i][j];
                ans = max (ans, val);
                for (int t = max (1, k - 1); t <= k + 1; t++)
                    if (i + t <= x)
                        f[i + t][t - d + 250] = max (f[i + t][t - d + 250], val + a[i + t]);
            }
        printf ("%d
    ", ans - 1);
    }
    View Code

    B.Mr. Kitayuta's Technology

         [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 = 120009;
    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] = 1;
        for (int i = head[u]; i; i = edge[i].next) {
            int v = edge[i].v;
            if (!vis[v])     dfs (v);
            if (vis[v] == 1) cycle[find (u)] = 1;
        }
        vis[u] = 2;
    }
    int main() {
        scanf ("%d %d", &n, &m);
        for (int i = 1; i <= n; i++) f[i] = i, siz[i] = 1;
        for (int i = 1, x, y; i <= m; i++) {
            scanf ("%d %d", &x, &y);
            adde (x, y);
            if (find (x) != find (y) ) uin (x, y);
        }
        for (int i = 1; i <= n; i++)
            if (!vis[i]) dfs (i);
        for (int i = 1; i <= n; i++) {
            if (find (i) == i)
                ans += siz[i] - 1;
            ans += cycle[i];
        }
        printf ("%d
    ", ans);
    }
    View Code

    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 = 100009;
    
    unordered_map<int, int> f[INF], old[INF];
    
    int n, m, q;
    inline int find (int x, int c) {
        if (f[x][c] < 0) 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] = -1;
        if (f[y].find (c) == f[y].end() ) f[y][c] = -1;
        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 = 1, 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 = 0;
                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
    ", old[a][b]);
        }
    }
    View Code
  • 相关阅读:
    [LeetCode]2. Add Two Numbers链表相加
    Integration between Dynamics 365 and Dynamics 365 Finance and Operation
    向视图列添加自定义图标和提示信息 -- PowerApps / Dynamics365
    Update the Power Apps portals solution
    Migrate portal configuration
    Use variable to setup related components visible
    Loyalty management on Retail of Dynamic 365
    Modern Fluent UI controls in Power Apps
    Change screen size and orientation of a canvas app in Power App
    Communication Plan for Power Platform
  • 原文地址:https://www.cnblogs.com/keam37/p/4237581.html
Copyright © 2011-2022 走看看