首页 > 其他分享 >CSP2022 假期计划 题解

CSP2022 假期计划 题解

时间:2023-02-15 07:55:05浏览次数:41  
标签:PII idx 假期 题解 CSP2022 ne int continue rightarrow

给你一张 \(n\) 个点, \(m\) 条边的无向图, 每个点有点权, 要求你在图中选出 \(A\), \(B\), \(C\), \(D\) 四个点, 使得 \(1\rightarrow A\rightarrow B\rightarrow C\rightarrow D\rightarrow 1\) 中, 前一个点到后一个点距离不超过 \(k\) 条边, 并且四个点点权之和最大

算法1

测试点 \(1\sim 8\) 满足 \(n\le 30\), 可以直接枚举 \(A, B, C, D\) 四个点, 时间复杂度 \(O(n^4)\), 期望得分 \(40\rm {pts}\)

算法2

考虑减少枚举的点的数量, 如果 \(A, B, C\) 已经确定, 那么 \(D\) 就可以不用枚举了, 直接取在 \(C\) 的 \(k\) 步之内并且在 \(1\) 的 \(k\) 步之内并且没有被取过的最大值(通过预处理一个点可达并且从 \(1\) 可达的前三大)即可, 这一步需要预处理出每个点到其他所有点的距离, 因为没有边权所以可以 \(O(N^2)\) 解决, 时间复杂度 \(O(n^3)\), 期望得分 \(70\rm {pts}\)

算法3

可以发现, 只要 \(C\) 点固定了 \(D\) 点就是固定的, 所以考虑用同样的方法维护 \(A\) 点, 只要 \(B\) 固定了 \(A\) 同样是固定的, 类似上面即可, 时间复杂度 \(O(n^2)\), 期望得分 \(100\rm {pts}\)

#include <bits/stdc++.h>

using namespace std;
const int N = 2510, M = 2e4 + 10;
const int inf = 0x3f3f3f3f;
typedef pair<long long, int> PII;
int e[M], ne[M], h[N], G[N][N], idx;
long long w[N];
PII f[N][3];
bool st[N];
int n, m, k;

inline void add(int a, int b){
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
    e[idx] = a, ne[idx] = h[b], h[b] = idx++;
}

bool cmp(PII a, PII b){
    return a.first > b.first;
}

void bfs(int z){
    queue<int> q;
    q.push(z);
    G[z][z] = -1;
    while(!q.empty()){
        int u = q.front();
        q.pop();
        for(int i = h[u]; ~i; i = ne[i]){
            int v = e[i];
            if(G[z][v] != inf)
                continue;
            
            G[z][v] = G[z][u] + 1;
            q.push(v);

            //如果这个点在家附近并且从这个点出发可以到达
            if(st[v] && G[z][v] <= k){
                PII tmp[4];
                for(int i = 0; i < 3; i++)
                    tmp[i] = f[z][i];
                tmp[3].first = w[v];
                tmp[3].second = v;
                sort(tmp, tmp + 4, cmp);
                for(int i = 0; i < 3; i++)
                    f[z][i] = tmp[i];
            }
        }
    }
    
}

int main(){
    memset(h, -1, sizeof h);
    memset(G, 0x3f, sizeof G);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 2; i <= n; i++){
        scanf("%lld", &w[i]);
    }
    for(int i = 1; i <= m; i++){
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b);
    }
    for(int i = 1; i <= n; i++){
        for(int j = 0; j < 3; j++)
            f[i][j] = {-1, 0};
    }
    
    st[1] = false;
    queue<int> q;
    q.push(1);
    G[1][1] = -1;
    while(!q.empty()){
        int u = q.front();
        q.pop();
        for(int i = h[u]; ~i; i = ne[i]){
            int v = e[i];
            if(G[1][v] != inf)
                continue;

            G[1][v] = G[1][u] + 1;
            q.push(v);

            if(G[1][v] <= k)
                st[v] = true;
        }
    }

    for(int i = 2; i <= n; i++){
        bfs(i);
    }
    
    long long ans = -1;
    for(int b = 2; b <= n; b++){
        for(int c = 2; c <= n; c++){
            if(G[b][c] > k || b == c)
                continue;
            for(int i = 0; i < 3; i++){
                int a = f[b][i].second;
                if(a == 0) 
                    break;
                for(int j = 0; j < 3; j++){
                    int d = f[c][j].second;
                    if(d == 0)
                        break;
                    if(d == a || b == c || a == c || d == b)
                        continue;
                    ans = max(ans, w[a] + w[b] + w[c] + w[d]);
                }
            }
        }
    }
    printf("%lld\n", ans);
    return 0;
}

标签:PII,idx,假期,题解,CSP2022,ne,int,continue,rightarrow
From: https://www.cnblogs.com/lostintianyi/p/17121414.html

相关文章

  • DTOJ 2023.02.11 测试 题解
    DTOJ2023.02.11测试题解2023省选模拟Round#12\(100+8+50=158\)还行T2想到了,但是没写,我觉得写了也不一定写得出来,挺妙的T1题意http://59.61.75.5:18018/p/545......
  • 读者最需要什么样的题解
    哈哈,其实还是鲜花,主要是看到\(\text{f}\color{red}{\text{eecle6418}}\)的这篇题解有感而发,当然我自己写的题解也很抽象,需要改正。当然这里的写题解是指主动打算写一......
  • 小孩召开法 题解
    开题之前の一些废话:小孩召开法,旦写一北砬。梦厷停留在,破了大式様。——龚诗锋《炄勺,砒》小孩。又是我很不会的排列计数。而且神题。久仰大名。现在是2月13日......
  • ARC120C Swaps 2 题解
    好难啊,会也不会设\(a_i=x,a_{i+1}=y\),那么交换后\(a_i=y+1,a_{i+1}=x-1\),发现交换后就是\(a_i+i\)和\(a_{i+1}+i+1\)这两个值进行了交换。那就把所有\(a_i\)变成......
  • 青龙面板调试运行代码时打印语句可能不执行的问题解决
    记录一次用青龙面板调试调用chatGPT的API时发现的一个问题:脚本在调试运行时,有可能会不显示部分打印语句的,例如node.js(python也有这种情况),如下图:关于为什么会出现此问题......
  • lg9018题解
    #include<bits/stdc++.h>usingnamespacestd;#defineN2000010#defineintlonglong#definemo1000000007intjc[N],ij[N],n,a[N];intc(inty,intx){ if(y<x)......
  • 【题解】ARC153 A-D
    怎么感觉ARC困难的永远是B题[惊恐]A.AABCDDEFE题目分析:完全可以把相等的位置合并在一起,这样就剩下了\(6\)个位置,然后就转化为了第\(N\)小的六位数是多少,这应该......
  • Magic Powder - 1 题解
    更好的阅读体验1.题意题目大意就是一块曲奇饼干需要\(n\)种食材,第\(i\)种需要\(a_i\)克,而你手中有这种食材\(b_i\)克,还有另外\(k\)克食材每一克可以代替任何......
  • Magic Powder - 2 题解
    更好的阅读体验1.题意题目大意就是一块曲奇饼干需要\(n\)种食材,第\(i\)种需要\(a_i\)克,而你手中有这种食材\(b_i\)克,还有另外\(k\)克食材每一克可以代替任何......
  • Rescheduling the Exam 题解
    题意:题意简单明了,就不多赘述了。解题方法:这道题我们要考虑贪心。由于我们只有一次修改\(a_i\)的机会,所以我们修改的值一定是产生最小距离的两个相邻的点之中修改。那......