【JZOJ4597】现世斩
2016-07-18 09:59
232 查看
Description
异变又发生了,魂魄妖梦作为幻想乡的一名自(cheng)机(guan),主动前去解决异变。我们用一个n个点、m条边的无向联通图来表示妖梦可选择的路线,妖梦从白玉楼出发,白玉楼被视为编号为1的点,编号为2——n的点是幻想乡的村庄,其中编号为n的村庄发生了异变。
每条边上可能会有一些妖怪袭击人类(然而妖梦是半人半灵),所以对于第i条边,妖梦需要t[i]分钟通过这条路。妖梦带了她的人符[现世斩],可以使所有连接点x的边的通过时间变成1(x可以任意指定)。然而为了保留足够的力量解决异变,妖梦只会用这个符卡一次。妖梦想知道,她到达村庄n的最短时间是多少。
Solution
显然把原图分成三层,跑一次最短路即可。Code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define fo(i,j,k) for(int i=j;i<=k;i++) #define N 300001 #define M 4000001 #define ll long long using namespace std; int to[M],next[M],last[M],val[M],num=0; void link(int x,int y,int c) { num++; to[num]=y; next[num]=last[x]; last[x]=num; val[num]=c; } int d[M]; ll dis ; bool vis ; void spfa(int s) { memset(dis,60,sizeof(dis)); dis[1]=0; vis[1]=true; d[1]=1; int l=0,r=1; while(l<r) { int x=d[++l]; for(int i=last[x];i;i=next[i]) { int v=to[i]; if(dis[x]+val[i]<dis[v]) { dis[v]=dis[x]+val[i]; if(!vis[v]) { vis[v]=true; d[++r]=v; } } } vis[x]=false; } } int main() { freopen("cut.in","r",stdin); freopen("cut.out","w",stdout); int n,m; cin>>n>>m; fo(i,1,m) { int u,v,w; scanf("%d %d %d",&u,&v,&w); if(u!=v) { link(u,v,w); link(v,u,w); link(u,v+n,1); link(u+n,v+n*2,1); link(v,u+n,1); link(v+n,u+n*2,1); link(u+n*2,v+n*2,w); link(v+n*2,u+n*2,w); } } spfa(1); cout<<dis[n*3]; }
相关文章推荐
- OSI模型
- 做外贸十大不能接的订单!
- ViewPager,PagerAdapter,FragmentPagerAdapter,FragmentStatePagerAdapter的API介绍翻译
- Shuffle related problem.
- HTML5离线篇收藏--- cache manifest
- 把数组排成最小的数 java
- cmd中输入mysql提示既不是内部命令的问题解决
- UniversalImageloader使用中遇到的问题
- 微信登录问题
- windows下python模拟鼠标点击和键盘输示例
- Hibernate Criteria对象详解
- OAuth授权的java实现详解
- SSD:Single Shot MultiBox Detector 心得 之神经网路(持续更新中。。。)
- mac osx安装配置mysql5.7[dmg包安装&启动&修改密码&登录]
- 【Leetcod 动态规划】 子数组最大和一类的问题
- 发现个不错的OJ题目分类网站
- iPad Pro 9.7/12.9寸对比测评
- ros导航资源
- Maven中的pom.xml详解
- linux下vi命令大全