关于 [CSP-S 2022] 假期计划 的一些想法

洛谷链接

考场算法

这题暴力其实很好想,但是我觉得暴力太低级了,所以就直接跳过了第一步。然而我的分数其实比暴力的还少一点(悲)。
首先,为了判断能吧哪里作为景点,首先跑一次最短路,记录每个点之间的距离。接下来在选择点的时候,我想到了这么一个东西。

#mermaid-svg-tLA04eQFq3dIxpT6 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-tLA04eQFq3dIxpT6 .error-icon{fill:#552222;}#mermaid-svg-tLA04eQFq3dIxpT6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tLA04eQFq3dIxpT6 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-tLA04eQFq3dIxpT6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tLA04eQFq3dIxpT6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tLA04eQFq3dIxpT6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tLA04eQFq3dIxpT6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tLA04eQFq3dIxpT6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tLA04eQFq3dIxpT6 .marker.cross{stroke:#333333;}#mermaid-svg-tLA04eQFq3dIxpT6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tLA04eQFq3dIxpT6 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tLA04eQFq3dIxpT6 .cluster-label text{fill:#333;}#mermaid-svg-tLA04eQFq3dIxpT6 .cluster-label span{color:#333;}#mermaid-svg-tLA04eQFq3dIxpT6 .label text,#mermaid-svg-tLA04eQFq3dIxpT6 span{fill:#333;color:#333;}#mermaid-svg-tLA04eQFq3dIxpT6 .node rect,#mermaid-svg-tLA04eQFq3dIxpT6 .node circle,#mermaid-svg-tLA04eQFq3dIxpT6 .node ellipse,#mermaid-svg-tLA04eQFq3dIxpT6 .node polygon,#mermaid-svg-tLA04eQFq3dIxpT6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tLA04eQFq3dIxpT6 .node .label{text-align:center;}#mermaid-svg-tLA04eQFq3dIxpT6 .node.clickable{cursor:pointer;}#mermaid-svg-tLA04eQFq3dIxpT6 .arrowheadPath{fill:#333333;}#mermaid-svg-tLA04eQFq3dIxpT6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tLA04eQFq3dIxpT6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tLA04eQFq3dIxpT6 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-tLA04eQFq3dIxpT6 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-tLA04eQFq3dIxpT6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tLA04eQFq3dIxpT6 .cluster text{fill:#333;}#mermaid-svg-tLA04eQFq3dIxpT6 .cluster span{color:#333;}#mermaid-svg-tLA04eQFq3dIxpT6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tLA04eQFq3dIxpT6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

景点A
景点B
景点C
景点D

整个过程可以从中间断开,分成前后两端,每一段的过程都可以描述为1 - x - y。最后找解的时候就在这么一个储存的数组里面找就可以了。
然而在这之后我算法的所有瓶颈都出在找的这个地方。在考场上我最后决定用贪心找。把这些状态放到一个优先队里面,然后找能和最大的匹配的另一半。最后得了55分(悲)。

代码

#include <bits/stdc++.h>
using namespace std;struct node {int id, dep; node (int id_, int dep_) {id = id_;dep = dep_;}
};struct res {int p1, p2;unsigned long long num;res (int p1_, int p2_, unsigned long long num_) {p1 = p1_;p2 = p2_;num = num_;}bool operator < (const res x) const {if (num < x.num) return true;else return false;}
};priority_queue <res> pue;
queue <node> que;
int n, m, k, dis[2510][2510];
unsigned long long score[2510];
bool vh[2510];
vector <int> p[2510];void work_dis (int fa, int ori) {dis[fa][fa] = ori;vh[fa] = 1;que.push (node (fa, ori));while (!que.empty()) {node f = que.front();que.pop();for (int i = 0; i < p[f.id].size(); ++i) {if (vh[p[f.id][i]]) continue;vh[p[f.id][i]] = 1;dis[fa][p[f.id][i]] = dis[fa][f.id] + 1;que.push (node (p[f.id][i], dis[fa][f.id] + 1));}}
}void dfs (int pos, int fa, int dep, unsigned long long val) {if (dep > 1) {if (pos != 1) pue.push (res (pos, fa, val));return;}for (int i = 1; i <= n; ++i) {if (dis[pos][i] == -1 || dis[pos][i] > k) continue;dfs (i, pos, dep + 1, val + score[i]);}
}bool check (res x, res y) {if (x.p1 != y.p1 && x.p2 != y.p2 && x.p1 != y.p2 && x.p2 != y.p1) return true;return false;
}int main() {//freopen ("holiday.in", "r", stdin);//freopen ("holiday.out", "w", stdout);memset (dis, -1, sizeof (dis));cin >> n >> m >> k;for (int i = 2; i <= n; ++i)cin >> score[i];for (int i = 1; i <= m; ++i) {int u, v;cin >> u >> v;p[u].push_back (v);p[v].push_back (u);}for (int i = 1; i <= n; ++i) {memset (vh, 0, sizeof (vh));work_dis (i, -1);}dfs (1, 1, 0, 0);res r1 = pue.top();pue.pop();while (!check (r1, pue.top())) pue.pop();cout << r1.num + pue.top().num << endl;//fclose (stdin);//fclose (stdout);return 0;
}

后来

上面的这个代码貌似有点问题,但是我也懒得改了。首先貌似是存状态的时候个别状态方向反了。然后好像在判断两个一半之间能不能联通、有没有重复的时候也有点问题。
但是在这之后我总的方向还是没变的。经过我不懈的尝试 我发现匹配两半的时候,设状态总数为 T T T,那么在前 T T T个分数最大的方案和前 T l o g T TlogT TlogT个最大方案中匹配能通过的点数最多。对此,我的猜想是:大部分有用的解都集中在前面,而这种枚举方式能最大限度地在最优解中匹配,而且数量相对平衡。总之是没啥正理 经过玄学优化枚举范围后的代码能A掉所有的官方数据,而且只有一个民间数据WA掉了。

代码

#include <bits/stdc++.h>
using namespace std;struct node {int id, dep; node (int id_, int dep_) {id = id_;dep = dep_;}
};struct res {int p1, p2;unsigned long long num;bool operator < (const res x) const {if (num > x.num) return true;else return false;}
};queue <node> que;
int n, m, k, dis[2510][2510], cnt, logn[6000010];
unsigned long long score[2510];
bool vh[2510];
res ans[6000010];
vector <int> p[2510];void work_logn() {logn[1] = 0;for (int i = 2; i <= cnt; ++i)logn[i] = logn[i / 2] + 1;
}void work_dis (int fa, int ori) {dis[fa][fa] = ori;vh[fa] = 1;que.push (node (fa, ori));while (!que.empty()) {node f = que.front();que.pop();for (int i = 0; i < p[f.id].size(); ++i) {if (vh[p[f.id][i]]) continue;vh[p[f.id][i]] = 1;dis[fa][p[f.id][i]] = dis[fa][f.id] + 1;que.push (node (p[f.id][i], dis[fa][f.id] + 1));}}
}void dfs (int pos, int fa, int dep, unsigned long long val) {if (dep > 1) {if (pos != 1) ans[++cnt] = {fa, pos, val};return;}for (int i = 1; i <= n; ++i) {if (dis[pos][i] == -1 || dis[pos][i] > k) continue;dfs (i, pos, dep + 1, val + score[i]);}
}bool check (res x, res y) {if (x.p1 != y.p1 && x.p2 != y.p2 && x.p1 != y.p2 && x.p2 != y.p1) return true;return false;
}bool check_link (int x, int y) {if (dis[x][y] <= k && dis[x][y] != -1) return true;return false;
}int main() {memset (dis, -1, sizeof (dis));cin >> n >> m >> k;for (int i = 2; i <= n; ++i)cin >> score[i];for (int i = 1; i <= m; ++i) {int u, v;cin >> u >> v;p[u].push_back (v);p[v].push_back (u);}for (int i = 1; i <= n; ++i) {memset (vh, 0, sizeof (vh));work_dis (i, -1);}dfs (1, 1, 0, 0);work_logn();sort (ans + 1, ans + 1 + cnt);unsigned long long maxn = 0;for (int i = 1; i <= n; ++i)for (int j = i + 1; j <= n * logn[cnt]; ++j)if (check (ans[i], ans[j]) && check_link (ans[i].p2, ans[j].p2) && maxn < ans[i].num + ans[j].num) maxn = ans[i].num + ans[j].num;cout << maxn << endl;return 0;
}

由于 T T T约等于 n 2 n ^ 2 n2,这个方法的时间复杂度差不多是 n 2 l o g n n ^ 2 log n n2logn,时间上问题不大。
然后在洛谷上看到一篇题解,思路和我的差不多,但是在匹配两半的时候边统计边找最大值,时间复杂度一样,但是可以匹配完所有的,具体没看懂。
大致上对于官方数据而言,我的任务完成了。但是真正的算法,还是需要我继续去想一想的。

关于 [CSP-S 2022] 假期计划 的一些想法相关推荐

  1. [CSP-S 2022] 假期计划

    题目传送门 [CSP-S 2022] 假期计划(民间数据) 题目描述 小熊的地图上有 n n n 个点,其中编号为 1 1 1 的是它的家.编号为 2 , 3 , - , n 2, 3, \ldots ...

  2. 【题解】P8817 [CSP-S 2022] 假期计划(bfs,dfs)

    [题解]P8817 [CSP-S 2022] 假期计划 此题作为 CSP-S 的 T1,可以说是相当有难度了.感觉 T1 和 T2 换了个位置.(雾) 我作为场外 VP 选手赛时此题只得了 95pts ...

  3. [CSP-S 2022] 假期计划题解

    假期计划 题目来源: CSP-S 2022 T1 题目描述 小熊计划从家出发去 4 4 4 个不同的景点游玩,完成 5 5 5 段行程后回家:家 → 景点 A A A → 景点 B B B → 景点 ...

  4. 【spfa】假期计划(jzoj 3936)

    假期计划 jzoj 3936 题目大意 给你一个有向图(n,m⩽20000n,m\leqslant 20000n,m⩽20000),现在有一些作为枢纽的点,且保证每一条边的两个点至少有一个是枢纽点,现 ...

  5. 还没做2022年计划?这个超赞工具送给你

    又到了一年制定计划的时候了. 你可能要说,每年的计划在年终回顾时,都实现不了,除了发个朋友圈过下瘾,计划还有什么用呢? 这里其实是2个问题: 1.计划如何实现? 2.计划有什么用? 01 对于计划如何 ...

  6. 朝花夕拾 - 基金定投回顾及 2022 定投计划

    风险提示:本次分析仅供参考,不作为投资策略推荐和收益保证,历史业绩不代表未来表现 基金投资有风险,请谨慎选择! 一 前言 经过 2018/2019 的混乱投资,2020 开始主动分析定投,2021 出 ...

  7. 2021的计划2022的计划

    山高水远,总有新的征程等着你我征服,就像跨过每一座山,趟过每一条河. 2021年末,总想着总结些什么,回头发现,想的太多,做的太少.很多时候,我都是行动上的矮子,思想上的巨人.却深知在未来我们时刻警惕 ...

  8. 2021年年终总结 2022年计划

    嗨,一转眼2021又过去了(貌似每年都是一转眼):最近几年总是给人一种时间过得越来越快的感觉,很神奇.无论你在哪里,在干什么,时间总是奔流不息的向前:2021年很快,2022年或许会更快,时间总是给人 ...

  9. 计算机假期计划内容,2019寒假计划,超详细学习计划表

    [导语]愉快的寒假已经开始了,基于拓宽知识面的目的,按时学习生活,做事有规律,度过一个快乐充实有意义的寒假,因此制定一个合理的寒假学习计划对初中孩子们是非常有必要的.下面为您制定具体计划如下.以下内容 ...

最新文章

  1. 如何现在就用到 Ubuntu 21.10
  2. 一文读懂支持向量机SVM(附实现代码、公式)
  3. mongodb spring 超时时间_spring data mongodb 配置遇到的几个问题
  4. i7 8750h支持linux,i7 8750H好吗i7 8700和8750H性能差别大吗?
  5. IDL | 实验一、IDL编码与运行
  6. win10未能连接网络连接到服务器,win10以太网无法连接网络解决办法
  7. 如何下载斗鱼回放视频(纯手工)
  8. 为你的整轨APE音乐制作CUE文件(图文)
  9. 判断一个很大的数是否是11的倍数(2种做法)
  10. 业务部门战略规划与支撑部门战略规划
  11. 机器学习笔记(九)——数据降维:主成分分析法(PCA)
  12. TAOUP初译稿:提交版本
  13. 【HBUOJ】暴躁的阿生
  14. p5.js 和 Processing 的恩怨情仇
  15. 传感器实训心得体会_传感器实训心得体会
  16. 一、为什么要做接口自动化,怎样做
  17. 微软专利展示了具有灵活触控笔的双屏设备
  18. windows 命令提示符 修改/prompt
  19. PLSQL-Initialization error
  20. matlab 学自动驾驶(3) 建立一个驾驶场景并生成综合检测——driving scenario Designer

热门文章

  1. 简单介绍一下经济学中 比较优势 的概念
  2. AGV小车如何实现无人搬运自动导引代替人工
  3. 小程序脚本语言WXS,你想要的都在这里了
  4. 20行Python代码,轻轻松松获取各路书本,你还在花钱买着看嘛~
  5. word2010打开97-03格式的word文件失败的解决方法
  6. Mybatis之批量更新数据(批量update)
  7. 007-安装百度云,搜狗输入法,播放器
  8. String[]数组初始化
  9. 华为鸿蒙2系统harmonyOS,华为鸿蒙HarmonyOS 2.0Beta版官方
  10. 如何提高自己的专注度