首先发出题目链接:
链接:https://ac.nowcoder.com/acm/contest/551/F
来源:牛客网
涉及:有向图


题目如下:



题目意思(表示我太chun,读了几遍才勉强明白了题目意思):

首先输入三个数n,m,s;
n是有多少个学员(dalao),m是学员之间的强弱关系有几条,s是所有学员即将分的所有题目;

下面每一行代表一种学员之间的强弱关系x,y,z
其中x和y指学员编号且y学员比x牛逼,如果x学员做了a道题,那么y学员至少要做a+r∗ka+r*ka+r∗k道题(比如输入1 3 0指3号学员比1号学员牛逼,如果1号学员做了0道题,那么3号学员就至少要做r∗kr*kr∗k道题)

也就是说,在所有的学员关系中,至少有一个最牛逼的学员,也至少有一个最菜的学员,


这样想一想,这不就是一个有向图吗?每条学员关系就是一条有向路,从x走向y的一条路,然后r算是一条路的权值,每条路的路径长为起点的值a+边权r*常数k(a+r∗ka+r*ka+r∗k),每一个点都有一个值。

最菜学员的编号是图的起点,最牛逼学员的编号是图的终点
ps:起点和终点不是唯一的!

而现在让你做的事情就是,找一个最大的k值,使从每一个图的起点到每一个图的终点的路程最大(所以理所当然,图起点的值为0),每一个点的值代表从图的起点到这个点的最短距离中的最大的一个值,所有点的值之和不能超过s。

所以这个题实质是:多源有向图最长路径问题


有向图一般可以用vector来存,为了方便,可以创建一个数对类型的vector(地图)

typedef pair<int,int> P;
vector<P> vec;

其中数对first代表一条有向边的终点,second代表这条边的边权;
vector下标代表这条边的起点(比如vec[1]=P(2,3)指起点是1号点,终点是2的一条边权为3的边)

有了地图,如何找到合适的k值,使得k值最大,且图中所有点的值之和不超过s。

对于k值,肯定不能从0开始一个个来模拟搜索,可以采用二分的方式来判断k可以有多大。
k的大概范围从0到s/max(r)s/max(r)s/max(r),max(r)max(r)max(r)指所有边权中最大的边权
证明:我们取极限情况,图中只有两个点,起点值为0,终点的值就是s,此时k值最大为s/max(r)s/max(r)s/max(r),在这个情况下,图中只有一条路,只有一个边权,所以max(r)=rmax(r)=rmax(r)=r。如果继续往图中加点连边,k只会越来越小,所以k的最大范围是s/max(r)s/max(r)s/max(r))

ps:特判,当所有边权全为0时,k是无限大的!!


有了k值,然后进行模拟,需要从图的起点开始往图的终点来计算(优先宽度搜索),使每一个点到图的起点的距离最短,取所有最短距离中最大的值作为这个点的值(因为要满足题目中的“至少”)。

为了寻找到到这个点所有最短距离中最大的值,可以先判断终点为此点的所有边,每次选择最大a+k*r的值即可,可以使用队列实现过程

(可以定义一个数组big,big[i]存终点为i的边的个数,每次访问了终点为i的边后,big[i]减一,当big[i]=0时,说明所有终点为i的边全部访问完毕,i这个点的值自然就是最大的a+k*r值,就可以把这个点放入队列内,开始搜索起点为此点的边,来更新更高级的点的值)

然后求所有点的值之和,如果大于s,说明k太大了,如果小于等于s,说明k太小了,然后一步步缩小k的范围,直到范围左边界大于右边界时,左边界的值减一就是答案;


比如实例一
地图:

0
2
2
1
4
1
3
4
2

k的范围是[first,second],此时first=0,second=4,k=(first+second)/2=2;
得到:

0
2
2
1
4
1:0
3:4
4:12
2:0
sum=16,ok

然后令first=k+1
k的范围是[first,second],此时first=3,second=4,k=(first+second)/2=3;
得到:

0
2
2
1
4
1:0
3:6
4:18
2:0
sum=24,no

然后令second=k-1
k的范围是[first,second],此时first=3,second=3,k=(first+second)/2=3;
得到:

0
2
2
1
4
1:0
3:6
4:18
2:0
sum=24,no

然后令second=k-1
second<first,跳出二分循环,得到k=first-1=2;

(记得一定要当first>second时才能跳出循环,不能first>=second时跳出,因为有可能当k=second时为答案!!!)


代码如下:

#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
typedef long long ll;
using namespace std;
ll first,second; //二分求k的左右范围
ll big[200005]={0};//b[i]记录终点为i这个点的边数
ll rbig[200005]={0};//big数组的拷贝,用于每次二分使用
ll d[200005]={0};//记录每个点的值
ll k=0,sum=0;//sum求所有点的值之和
ll maxr=0; //求最大的边权
typedef pair<int,int> P;
vector<P> vec[200005];//有向图的地图,记录每一条边,vec下标是边的起点,first是边的终点,second是边权
ll n,m,s,x,y,r;//题目涉及的变量
int main(){queue<ll> que;//宽搜每一个点scanf("%lld%lld%lld",&n,&m,&s);while(m--){//开始绘制地图,big记录终点为某个点的边数scanf("%lld%lld%lld",&x,&y,&r);maxr=max(maxr,r);vec[x].push_back(P(y,r));big[y]++;}if(!maxr){printf("-1");  return 0;}//特判first=0;second=s/maxr;      while(first<=second){//二分搜索kk=(first+second)/2;sum=0;while(!que.empty()) que.pop();//清空数组for(ll i=1;i<=n;i++){if(!big[i]) que.push(i);//将图的起点放入队列rbig[i]=big[i];//拷贝big数组d[i]=0;//清空所有点的值}  while(!que.empty()){ll p=que.front();  que.pop();sum+=d[p];//记录此点的值if(sum>s)  break;//如果sum>s直接跳出for(ll i=0;i<vec[p].size();i++){d[vec[p][i].first]=max(d[vec[p][i].first],d[p]+k*vec[p][i].second);//更新点的值rbig[vec[p][i].first]--; //未访问的终点为此点的边的数量减一if(rbig[vec[p][i].first]==0)   que.push(vec[p][i].first);//所有终点为此点的边全部被访问过,d[i]为最终值,将此点放入队列} }if(sum>s)   second=k-1;else    first=k+1;//改变范围}printf("%lld",first-1);return 0;
}

“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛----G-CSL的训练计划相关推荐

  1. “新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛 B.CSL 的英语考试

    CSL 的英语考试 CSL 为了备战即将到来的六级考试,在外面报了一个英语培训班.经过了一学期的学习后,英语老师决定要对 CSL 的学习成果进行检测.老师准备了一份卷子,考虑到 CSL 的英语水平,卷 ...

  2. 2020上海高校程序设计竞赛暨第18届上海大学程序设计联赛夏季赛(同步赛) B-分子

    2020上海高校程序设计竞赛暨第18届上海大学程序设计联赛夏季赛(同步赛) B-分子 题目描述: 在遥远的斯卡布罗集市,有机分子只能由 C, H, O 三种元素组成.根据珂学家们的探测,一个 C 原子 ...

  3. 2020上海高校程序设计竞赛暨第18届上海大学程序设计联赛夏季赛(同步赛)整理合集

    文章目录 分子 爵士 内存 同源 游戏 选择 露营 D.旅行 H.病毒 海高校程序设计竞赛暨第18届上海大学程序设计联赛夏季赛 分子 题目大意 在遥远的斯卡布罗集市,有机分子只能由 C,H,OC, H ...

  4. 【Java/补题/牛客/ACM赛制】2021年ICPC国际大学生程序设计竞赛暨陕西省第九届大学生程序设计竞赛(正式赛)

    文章目录 题目链接 知识一览 题目列表 快输 C - GCD(数论分块) 题目链接 2021年ICPC国际大学生程序设计竞赛暨陕西省第九届大学生程序设计竞赛(正式赛) 知识一览 01-数论分块 题目列 ...

  5. 好久没撸c,第一场回状态的题(埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛

    题目链接: 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 A:Wasserstein Distance ## 题意:有2大堆柱状图的土(总体积相同,问从第一堆土移动到第二堆消耗最少的 ...

  6. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 A-Wasserstein Distance

    埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 A-Wasserstein Distance 链接:https://www.nowcoder.com/acm/contest/91/A ...

  7. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 L-K序列

    埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 L-K序列 链接:https://www.nowcoder.com/acm/contest/91/L 来源:牛客网 题目描述 给一个数组 ...

  8. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 E-小Y吃苹果

    埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 E-小Y吃苹果 链接:https://www.nowcoder.com/acm/contest/91/E 来源:牛客网 题目描述 小Y买 ...

  9. “科大讯飞杯”第十七届同济大学程序设计预选赛暨高校网络友谊赛 F.排列计算

    "科大讯飞杯"第十七届同济大学程序设计预选赛暨高校网络友谊赛 F.排列计算 题目链接 题目描述 天才程序员菜哭武和石头组队参加一个叫做国际排列计算竞赛 (International ...

最新文章

  1. 最强 JDK15 安装与讲解,有点想升级,终于要废弃偏向锁了!
  2. iOS 汉字转拼音 PinYin4Objc
  3. 转载:LINQ to SQL更新数据库操作
  4. 关于Python异常处理,你需要了解的知识点
  5. cmd编译可以通过执行没有结果_Go语言是如何完成编译的
  6. sql活动监视器 死锁_使用system_health扩展事件监视SQL Server死锁
  7. Android 如何反编译apk查看源码
  8. Ubuntu 搜狗输入法 关闭简繁切换快捷键
  9. python12岁该学吗_本人12岁,对编程感兴趣,之前也学过python,被爸妈打消积极性,面对爸妈的反对,我该顺从还是继续?...
  10. wegame服务器维护启动游戏失败,wegame连接服务器失败
  11. ctab提取dna流程图_DNA提取(CTAB法)
  12. python爬虫爬取古诗词实例补充讲解之获取注释和译文
  13. Excel如何批量查询手机号码归属地
  14. node-addon-api的设计和实现
  15. java编程个人总结_java个人总结
  16. 智能坐便器雷达感应技术,微波雷达感应模组应用,雷达传感器方案
  17. 数据的探索性分析(EDA)
  18. idead打war包
  19. VCC VDD VSS
  20. ad域下文件服务器,ad域建立文件服务器

热门文章

  1. 关于新中新二代身份证读卡器DKQ-A16D的一些问题
  2. 管理会计习题集及答案 1-4章
  3. python量化:如何利用时间序列索引找到股票日线行情中的每个月的第一个交易日?每年的最后一个交易日?
  4. 中国人民大学孟生旺教授《金融数学》资源
  5. c语言用库函数求正弦数,用C语言求正弦值?
  6. 安装Ubuntu15.10后要做的事
  7. HomeBrew及HomeBrew Cask的简介和使用
  8. 【论文精读】The Devil is the Classifier: Investigating Long Tail Relation Classification with Decoupling
  9. QT绘制区域(ROI)框(矩形框和椭圆框)
  10. 编码器和解码器的概念理解