NOIP模拟赛(by hzwer) T3 小奇回地球
【题目背景】
开学了,小奇在回地球的路上,遇到了一个棘手的问题。
【问题描述】
简单来说,它要从标号为 1 的星球到标号为 n 的星球,某一些星球之间有航线。 由于超时空隧道的存在,从一个星球到另一个星球时间可能会倒流,而且,从星 球 a 到 b 耗费的时间和星球 b 到 a 耗费的时间不一定相同。宇宙法规定:“禁止在出发时间前到达目的地”。每艘飞船上都有速度调节装置,可以调节飞行的时间。其功能可以使得整次航程中所有两星球间的飞行时间增加或减少相同的整数值。你的任务是帮助它调整速度调节器,找出一条最短时间到达目的地的路径。
【输入格式】
输入文件包含多组数据,第 1 个数为 T,表示数据组数。对于每组数据,输入第 1 行为两个正整数 n,m,为星球的个数和星球间的路线数。接下来 m 行,每行三个整数 i,j 和 t,表示由星球 i 到星球 j 飞行的时间为 t。由 i 到 j 最多只会有一条飞行线路。
【输出格式】
输出文件共 T 行,每组数据输出一行。
如果可以通过调节速度调节器完成任务,则输出一个非负整数,表示由星球1到星球 n 的最短时间。(注意最短时间要大于或者等于 0)。如果不能由星球 1 到达星球 n,则输出-1。
【样例输入】
1
4 5
1 2 1
1 3 1
2 3 -3
3 1 1
3 4 1
【样例输出】
2
【样例解释】
把速度控制器的值设为 1,相当于每个时间值加 1,得到的最短路径为 1→2→3→4。所需时间为 2+(-2)+2=2。
【数据范围】
1,2 号测试点,保证所有星球出度不超过1
3,4 号测试点,n<=10
5,6 号测试点,-100<=t<=100
对于 100%的数据 T<=10,n<=100,m<=n*(n-1),-100000<=t<=100000
数据随机和构造结合生成
【解析】
将此题简化后可得如下模型:给定一张有向图(有负边权),可以使每一条边加上或减去一个值t,使从1到n的最短路径最小且非负。
经过分析可以知道,若给每一条边加上一个值t0后,1到n的最短路为负,那么对于任意t<t0都有最短路径仍为负。由此可以想到二分答案。t的值域为-100000到100000,那么二分的左右边界就定好了。然后每次都用SPFA检验最短路径是否大于等于0,然后......死循环了。
为什么呢?假设有t1<0,那么图中就有几率出现负权环,那么就没有最短路。所以要在SPFA中加入判断负权环的内容。但即使这样仍会超时。那么我们继续思考怎么优化。显然,如果一个点与1或n不连通,那么它对答案是没有贡献的。我们先从1出发遍历整张图,把无法到达的点删去。然后再从1能够到达的点出发,如果该点不能到达n,也从集合中删去。在“砍图”之后,虽然时间已经优化了,但仍然不够。题目中有一句话是这么说的:
数据随机和构造结合生成
那是不是会卡SPFA呢?所以,一个神奇的操作就出来了:深度优先搜索版SPFA。用DFS-SPFA去判断负权环即可。
【代码】
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define N 102
#define M 200002
using namespace std;int head[N],ver[M],nxt[M],edge[M],c;
int t,n,m,i,cnt[N],dis[N];
bool e[N],vis[N],in[N];
queue<int> q;
int read()
{
char c=getchar();
int w=,f=;
while(c<''||c>''){
if(c=='-') f=-;
c=getchar();
}
while(c<=''&&c>=''){
w=w*+c-'';
c=getchar();
}
return w*f;
}
void insert(int x,int y,int z)
{
c++;
ver[c]=y;
edge[c]=z;
nxt[c]=head[x];
head[x]=c;
}
bool dfs_SPFA(int x,int s)
{
vis[x]=;
for(int i=head[x];i;i=nxt[i]){
int y=ver[i];
if(dis[y]>dis[x]+edge[i]+s&&e[y]){
if(vis[y]) return ;
dis[y]=dis[x]+edge[i]+s;
if(dfs_SPFA(y,s)) return ;
}
}
vis[x]=;
return ;
}
void SPFA(int s)
{
memset(dis,0x3f,sizeof(dis));
memset(in,,sizeof(in));
q.push();
in[]=;
dis[]=;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];i;i=nxt[i]){
int y=ver[i];
if(dis[x]+edge[i]+s<dis[y]&&e[y]){
dis[y]=dis[x]+edge[i]+s;
if(!in[y]){
in[y]=;
q.push(y);
}
}
}
in[x]=;
}
}
void dfs(int x)
{
vis[x]=;
for(int i=head[x];i;i=nxt[i]){
int y=ver[i];
if(!vis[y]) dfs(y);
}
}
bool check(int x)
{
for(int i=;i<=n;i++){
if(e[i]){
memset(dis,0x3f,sizeof(dis));
memset(vis,,sizeof(vis));
if(dfs_SPFA(i,x)) return ;
}
}
SPFA(x);
if(dis[n]>=) return ;
return ;
}
int main()
{
freopen("earth.in","r",stdin);
freopen("earth.out","w",stdout);
cin>>t;
while(t--){
memset(e,,sizeof(e));
memset(head,,sizeof(head));
memset(vis,,sizeof(vis));
c=;
n=read();
m=read();
for(i=;i<=m;i++){
int u,v,w;
u=read();
v=read();
w=read();
insert(u,v,w);
}
dfs();
for(i=;i<=n;i++){
if(!vis[i]) e[i]=;
}
for(i=;i<=n;i++){
if(e[i]){
memset(vis,,sizeof(vis));
dfs(i);
if(!vis[n]) e[i]=;
}
}
int l=-,r=,mid,ans;
while(l<=r){
mid=(l+r)/;
if(check(mid)){
ans=dis[n];
r=mid-;
}
else l=mid+;
}
if(ans>1e9) cout<<"-1"<<endl;
else cout<<ans<<endl;
}
fclose(stdin);
fclose(stdout);
return ;
}
NOIP模拟赛(by hzwer) T3 小奇回地球的更多相关文章
- 2.17NOIP模拟赛(by hzwer) T3 小奇回地球
[题目背景] 开学了,小奇在回地球的路上,遇到了一个棘手的问题. [问题描述] 简单来说,它要从标号为 1 的星球到标号为 n 的星球,某一些星球之间有航线. 由于超时空隧道的存在,从一个星球到另一个 ...
- NOIP模拟赛(by hzwer) T2 小奇的序列
[题目背景] 小奇总是在数学课上思考奇怪的问题. [问题描述] 给定一个长度为 n 的数列,以及 m 次询问,每次给出三个数 l,r 和 P, 询问 (a[l'] + a[l'+1] + ... + ...
- NOIP模拟赛(by hzwer) T1 小奇挖矿
[题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值 w)的飞船,按既定 路线依次飞过喵星系的 n 个星球. [问题描述] 星球分为 2 类:资源型和维修型. 1. 资源型:含矿物质量 ...
- 2.17NOIP模拟赛(by hzwer) T2 小奇的序列
[题目背景] 小奇总是在数学课上思考奇怪的问题. [问题描述] 给定一个长度为 n 的数列,以及 m 次询问,每次给出三个数 l,r 和 P, 询问 (a[l'] + a[l'+1] + ... + ...
- 2.17NOIP模拟赛(by hzwer) T1 小奇挖矿
[题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值 w)的飞船,按既定 路线依次飞过喵星系的 n 个星球. [问题描述] 星球分为 2 类:资源型和维修型. 1. 资源型:含矿物质量 ...
- NOIP模拟赛 经营与开发 小奇挖矿
[题目描述] 4X概念体系,是指在PC战略游戏中一种相当普及和成熟的系统概念,得名自4个同样以“EX”为开头的英语单词. eXplore(探索) eXpand(拓张与发展) eXploit(经营与开发 ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 2015-9-13 NOIP模拟赛 by hzwer
好老的题了,但是还是很有做头的. 总结 不吸氧看来确实是没法用stl的啊(set常数太大了,开O2也没过) SPFA没认真学,觉得有堆优化Dijkstra就天下无敌了,今天负边权教我做人 于是苦逼的只 ...
- 2015-9-13 NOIP模拟赛解题报告(by hzwer)
小奇挖矿 「题目背景」 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞过喵星系的n个星球. 「问题描述」 星球分为2类:资源型和维修型. 1.资源型:含矿物质量a[i ...
随机推荐
- Spring MVC静态资源处理——<mvc:resources /> ||<mvc:default-servlet-handler />
优雅REST风格的资源URL不希望带 .html 或 .do 等后缀.由于早期的Spring MVC不能很好地处理静态资源,所以在web.xml中配置DispatcherServlet的请求映射,往往 ...
- win7自带录像工具怎么打开?win7自带录像工具的使用方法
http://www.xitongcheng.com/jiaocheng/win7_article_28327.html 制作教程的好帮手 win7自带录像工具怎么打开?win7自带录像工具的使用方法 ...
- 20191110 Spring Boot官方文档学习(4.2)
4.2.外部化配置 Spring Boot使您可以外部化配置,以便可以在不同环境中使用相同的应用程序代码.您可以使用Properties文件,YAML文件,环境变量和命令行参数来外部化配置.属性值可以 ...
- centos7 VM虚拟机在主机关机重启后,无法ping通
解决办法 1.虚拟机的某些网络相关的服务没有启动,打开电脑的服务启动相关服务 2.打开虚拟机的虚拟网络设置,恢复默认设置即可 3.判定虚拟网卡的网关和centos的网关是否一致,如果不一致,改成一致, ...
- mysql: show full processlist 详解
show full processlist 是显示用户正在运行的线程,需要注意的是,除了 root 用户能看到所有正在运行的线程外,其他用户都只能看到自己正在运行的线程,看不到其它用户正在运行的线程. ...
- centos 7 里如何判断IP是否合法
ip=123.23.2.32; [[ $ip =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9 ...
- [DS+Algo] 007 希尔排序及其代码实现
步骤 将数组列在一个表(一行多列)中,按特定的步长进行插入排序 步长从 length/2 到 1,每次除 2 将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序 算法性能 (根据步长序 ...
- eclipse中经常用到的修改菜单项
1.编写java程序时,书写一个类之后,要调用此类的某个方法时,点个点,此类的所有方法都会自动出现,然后再选择需要的那个方法即可: 2.鼠标放在一个类上面,关于此类的相关描述就会自动加载出来,要修改的 ...
- 极*Java速成教程 - (7)
Java高级特性 数组 在Java中,数组是一串连续的,不可改变长度的,对象被固定的,类型固定的连续空间.数组中的随机访问非常迅速,但为了速度放弃了灵活性.而效率也是数组最大的优点. 在使用泛型的容器 ...
- 洛谷 P2347 砝码称重 & [NOIP1996提高组](dp,枚举)
传送门 解题思路 一看数据范围<1000就坚定了我暴力的决心(不愧是1996年代的题还是t4QAQ) 所以很显然,暴力之中有一点dp的思想,就是把它们像多重背包一样拆分,拆成a1+a2+a3+a ...