tokitsukaze and Event————牛客练习赛50

2024-02-02 18:08

本文主要是介绍tokitsukaze and Event————牛客练习赛50,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接
https://ac.nowcoder.com/acm/contest/1080/D
思路
      题意是给你一个 n 个点 m 条边的无向图,不存在重边和自环,也没有负权边,但是每条边实际上存在两个权值,一个是原状态对应 ai 权值,一个是夜战状态对应 bi 权值,只能在途中某个位置切换形态且只能切换一次,最后到达终点时必须是夜战状态;此外,还增加了一个要求是游戏难度,当难度为 k 时,在1,2,3……,k-1处都不能切换形态,然后给定你起点 s 和终点 t ,让你输出从难度 1 到难度 n 的所有从 st 的最短路对应的权值和。
      我的想法是建立两个图,两个图唯一的不同是权值不同,一个对应 ai 权值,一个对应 bi 权值,然后分别对两个图求最短路,对于 ai 图以起点 s 为起点求最短路,对于bi图以终点 t 为起点求最短路,(这里采用SPFA求最短路),因为最开始一定是原状态,然后再切换到夜战状态,所以对于 ai 应以起点 s 为起点,对于 bi 应以终点 t 为起点,然后这两个图的最短路径分别存放于 dadb 两个数组中,然后从后往前遍历,切换状态对应的最小伤害就是 da[ i ] + db [ i ] ,因为根据前面的两次求最短路径,如果是在 i 处切换状态,那么路径就是 s -> i -> t,而 s -> i对应的最短路径就是da [ i ],i -> t对应的最短路径就是db [ i ]
      为什么这里采取从后往前遍历,因为一个很显然的结论,难度低的时候对应的最短路一定小于等于难度高的时候,那么比较过程肯定是拿上一个较高难度对应的值和当前的难度对应值相比较,否则难度从低到高的话,最后输出全是最低值,因为最短路径我们肯定是用min函数的。

c++代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;const int N=1e5+5;
const int INF=1e9+10;struct Graph
{vector<int> w;vector<int> edge;
}Ga[N],Gb[N];ll da[N],db[N],vis_a[N],vis_b[N],ans[N];
int n,m;void add(ll u,ll v,ll a,ll b)
{Ga[u].edge.push_back(v);Ga[u].w.push_back(a);Gb[u].edge.push_back(v);Gb[u].w.push_back(b);}void init()
{memset(da,INF,sizeof(da));memset(db,INF,sizeof(db));memset(vis_a,0,sizeof(vis_a));memset(vis_b,0,sizeof(vis_b));memset(ans,INF,sizeof(ans));
}int main()
{scanf("%d%d",&n,&m);for(int i=0;i<m;i++){ll u,v,a,b;scanf("%lld%lld%lld%lld",&u,&v,&a,&b);add(u,v,a,b);add(v,u,a,b);}init();ll s,t;scanf("%lld%lld",&s,&t);vis_a[s]=1;da[s]=0;queue<int> q1;q1.push(s);while(q1.size()){auto x=q1.front();q1.pop();vis_a[x]=0;for(int i=0;i<Ga[x].edge.size();i++){int j=Ga[x].edge[i];if(da[j]>da[x]+Ga[x].w[i]){da[j]=da[x]+Ga[x].w[i];if(!vis_a[j]){q1.push(j);vis_a[j]=1;}}}}vis_b[t]=1;db[t]=0;queue<int> q2;q2.push(t);while(q2.size()){auto x=q2.front();q2.pop();vis_b[x]=0;for(int i=0;i<Gb[x].edge.size();i++){int j=Gb[x].edge[i];if(db[j]>db[x]+Gb[x].w[i]){db[j]=db[x]+Gb[x].w[i];if(!vis_b[j]){q2.push(j);vis_b[j]=1;}}}}for(int i=n;i>=0;i--){ans[i]=min(ans[i+1],da[i]+db[i]);}for(int i=1;i<=n;i++){printf("%lld\n",ans[i]);}return 0;
}

这篇关于tokitsukaze and Event————牛客练习赛50的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/671544

相关文章

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

【附答案】C/C++ 最常见50道面试题

文章目录 面试题 1:深入探讨变量的声明与定义的区别面试题 2:编写比较“零值”的`if`语句面试题 3:深入理解`sizeof`与`strlen`的差异面试题 4:解析C与C++中`static`关键字的不同用途面试题 5:比较C语言的`malloc`与C++的`new`面试题 6:实现一个“标准”的`MIN`宏面试题 7:指针是否可以是`volatile`面试题 8:探讨`a`和`&a`

day-50 求出最长好子序列 I

思路 二维dp,dp[i][h]表示nums[i] 结尾,且有不超过 h 个下标满足条件的最长好子序列的长度(0<=h<=k),二维数组dp初始值全为1 解题过程 状态转换方程: 1.nums[i]==nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h]+1) 2.nums[i]!=nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h-1

牛客小白月赛100部分题解

比赛地址:牛客小白月赛100_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A.ACM中的A题 #include<bits/stdc++.h>using namespace std;#define ll long long#define ull = unsigned long longvoid solve() {ll a,b,c;cin>>a>>b>

牛客小白月赛100(A,B,C,D,E,F三元环计数)

比赛链接 官方讲解 这场比较简单,ABC都很签到,D是个不太裸需要预处理的 B F S BFS BFS 搜索,E是调和级数暴力枚举,F是三元环计数。三元环考的比较少,没见过可能会偏难。 A ACM中的A题 思路: 就是枚举每个边变成原来的两倍,然后看看两短边之和是否大于第三边即可。 不能只给最短边乘 2 2 2,比如 1 4 8 这组数据,也不能只给第二短边乘 2 2 2,比

fetch-event-source 如何通过script全局引入

fetchEventSource源码中导出了两种类型的包cjs和esm。但是有个需求如何在原生是js中通过script标签引呢?需要加上type=module。今天介绍另一种方法 下载源码文件: https://github.com/Azure/fetch-event-source.git 安装: npm install --save-dev webpack webpack-cli ts

笔试强训,[NOIP2002普及组]过河卒牛客.游游的水果大礼包牛客.买卖股票的最好时机(二)二叉树非递归前序遍历

目录 [NOIP2002普及组]过河卒 牛客.游游的水果大礼包 牛客.买卖股票的最好时机(二) 二叉树非递归前序遍历 [NOIP2002普及组]过河卒 题里面给的提示很有用,那个马的关系,后面就注意,dp需要作为long的类型。 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息publ

myEclipse失去焦点时报错Unhandled event loop exception的解决方案

一句话:百度杀毒惹的祸。。。。果断卸载后问题解决。

每日OJ_牛客_求和(递归深搜)

目录 牛客_求和(递归深搜) 解析代码 牛客_求和(递归深搜) 求和_好未来笔试题_牛客网 解析代码         递归中每次累加一个新的数,如果累加和大于等于目标,结束递归。此时如果累加和正好等于目标,则打印组合。向上回退搜索其它组合。此题本身就是一个搜索的过程,找到所有的组合。 #include <iostream>#include <cmath>#in

50. Pow(x,n)

题目: 解答: 主要是求 n &gt; 0 n &gt; 0 n>0 的情况的计算,其他时候,可以通过转换得到。 而 n &gt; 0 n &gt; 0 n>0 的情况下, ​ n = a 0 2 0 + a 1 2 1 + a 2 2 2 … a m 2 m n = a_0 2^0 + a_1 2^1 + a_2 2^2 \ldots a_m 2^m n=a0​20+a1​21