【题目背景】

  开学了,小奇在回地球的路上,遇到了一个棘手的问题。

【问题描述】

  简单来说,它要从标号为 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 <bits/stdc++.h>
#define N 102
#define M 200002 using namespace std; int head[N],ver[M],nxt[M],edge[M],c,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); t=read(); 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=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;
} return ;
}

P.S. 转载自LSlzf

2.17NOIP模拟赛(by hzwer) T3 小奇回地球的更多相关文章

  1. NOIP模拟赛(by hzwer) T3 小奇回地球

    [题目背景] 开学了,小奇在回地球的路上,遇到了一个棘手的问题. [问题描述] 简单来说,它要从标号为 1 的星球到标号为 n 的星球,某一些星球之间有航线. 由于超时空隧道的存在,从一个星球到另一个 ...

  2. 2.17NOIP模拟赛(by hzwer) T2 小奇的序列

    [题目背景] 小奇总是在数学课上思考奇怪的问题. [问题描述] 给定一个长度为 n 的数列,以及 m 次询问,每次给出三个数 l,r 和 P, 询问 (a[l'] + a[l'+1] + ... + ...

  3. 2.17NOIP模拟赛(by hzwer) T1 小奇挖矿

    [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值 w)的飞船,按既定 路线依次飞过喵星系的 n 个星球. [问题描述] 星球分为 2 类:资源型和维修型. 1. 资源型:含矿物质量 ...

  4. NOIP模拟赛(by hzwer) T2 小奇的序列

    [题目背景] 小奇总是在数学课上思考奇怪的问题. [问题描述] 给定一个长度为 n 的数列,以及 m 次询问,每次给出三个数 l,r 和 P, 询问 (a[l'] + a[l'+1] + ... + ...

  5. NOIP模拟赛(by hzwer) T1 小奇挖矿

    [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值 w)的飞船,按既定 路线依次飞过喵星系的 n 个星球. [问题描述] 星球分为 2 类:资源型和维修型. 1. 资源型:含矿物质量 ...

  6. NOIP模拟赛 经营与开发 小奇挖矿

    [题目描述] 4X概念体系,是指在PC战略游戏中一种相当普及和成熟的系统概念,得名自4个同样以“EX”为开头的英语单词. eXplore(探索) eXpand(拓张与发展) eXploit(经营与开发 ...

  7. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  8. 2015-9-13 NOIP模拟赛 by hzwer

    好老的题了,但是还是很有做头的. 总结 不吸氧看来确实是没法用stl的啊(set常数太大了,开O2也没过) SPFA没认真学,觉得有堆优化Dijkstra就天下无敌了,今天负边权教我做人 于是苦逼的只 ...

  9. 【20170521校内模拟赛】热爱生活的小Z

    学长FallDream所出的模拟赛,个人感觉题目难度还是比较适中的,难度在提高+左右,可能比较接近弱省省选,总体来讲试题考查范围较广,个人认为还是很不错的. 所有试题如无特殊声明,开启-O2优化,时限 ...

随机推荐

  1. json转义处理

    php把参数转成json字符串,中文会变成unicode,有部分会自动转义(添加反斜杠\) json_encode() #中文不转义对应的数字 256) json_encode($data,JSON_ ...

  2. with open()函数中,如何在文件名设置中引用变量(python)

    name = "wangyang" age = " with open("C:/Users/mike1/Desktop/name_age.txt", ...

  3. 安全 - 内容安全策略(CSP)(未完)

    威胁 跨站脚本攻击(Cross-site scripting) 跨站脚本攻击Cross-site scripting (XSS)是一种安全漏洞,攻击者可以利用这种漏洞在网站上注入恶意的客户端代码. 攻 ...

  4. PAT (Advanced Level) Practice 1028 List Sorting (25 分) (自定义排序)

    Excel can sort records according to any column. Now you are supposed to imitate this function. Input ...

  5. 360独角兽实习,连载周记(gnuradio 低功耗蓝牙BLE 综合工具模块编写)

    (有点乱,之后会有整理) 最近在用写一套gnuradio的OOT模块,主要用来进行BLE嗅探的,github上有了一些工具,可是他们并没有很好的模块化,于是打算自己写一个,这样以后做一些其他的项目,模 ...

  6. 合理使用Android提供的Annotation来提高代码的质量

    概述 Java语言提供了Annotation的机制,让描述性的元数据能够和代码共存.通常我们可以利用Annotation,来做一些标志性的说明.然而Annotation必须和相应的解析工具一起才能工作 ...

  7. 摇一摇—微信7.0.8版本audio无法自动播放问题

    近日有一个项目出现audio无法自动播放,查看原因才发现是微信版本更新为7.0.8版本,需要有交互行为,第一次播放需要用户手动点击一下,无法使用DOM中的play()进行直接播放操作,那怎么办呢? 通 ...

  8. Arcgis runtime sdk .net 二次开发

    前段时间研究了下 arcgis runtime sdk .net 二次开发··这里做个笔记 runtime版本为100.6 基于WPF 开发 命名空间引入 xmlns:esri="http: ...

  9. PHP目录操作(附封装好的目录操作函数文件)

    目录函数库常用API $path='test'; var_dump(is_dir($path));//检测是否为目录 echo '<hr/>'; echo getcwd();//得到当前的 ...

  10. mysql 视图 触发器 存储过程 函数事务 索引

    mysql 视图 触发器 存储过程 函数事务 索引 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当 ...