POJ 1613/ZOJ 1791 Cave Raider(bellman-ford)
来源:互联网 发布:js a disabled属性 编辑:程序博客网 时间:2024/05/22 10:51
链接:http://poj.org/problem?id=1613
这题被无向边坑了很久,wa了好多次,最后从有向边改成无向边就过了。
样例解释:
2 2 1 21 2 5 4 10 14 20 24 301 2 6 2 10 22 30第一行表示:2个点,2种边,起点,终点
第二行的1 2 5表示从1到2,权值为5(当然,这是无向边,反方向也是),后面的4,10,14,20,24,30分别表示开启和关闭,这里的就是:4时刻关闭,10时刻开启,14时刻关闭,20时刻开启,24时刻关闭,30时刻开启,如果最后一个是开启的话,之后就是永久开启,最后一个是关闭的话,之后就是永久关闭,使用这个边的时候要求在进入和出去的时候都在同一个开启的时间段,比如10-14,20-24,30-INF,不能中间夹杂着关闭。输入的时候也很奇怪,我自己写了一个读入数字的,但是出错了,不知道是数据里有非法字符还是我写错了,最后用stringstream解决。
思路:
这题只给了你点和边,但是根据样例,会在相同两个点之间产生不同权值的边,所以就不能用dijkstra,所以我就想到了用bellman-ford来解决这题,只要对边进行遍历就可以求出最短路。但是这题对边的使用有时间限制,所以在松弛的时候判断一下当前这条边能否使用就可以了。
代码:
#include<stdio.h>#include<string.h>#include<vector>#include<string>#include<sstream>#include<queue>#include<cctype>#include<iostream>#include<algorithm>using namespace std;const int N=50;const int INF=1e9+10;struct Edge{ int st,to,v; vector<int> time; Edge(){} Edge(int a,int b,int c){st=a,to=b,v=c;time.clear();}};int n,m,st,ed,d[N+10];vector<Edge>edge;int allow(int t,int id,int vv){ vector<int> &s=edge[id].time; int i=0,flag=1;//s[0]的时候是0时刻,从0时刻开始 for(i=0;i<s.size()-1;i++,flag^=1){//用flag标记当前这条通道是开启还是关闭 if(flag&&s[i]>=t&&s[i+1]-s[i]>=vv)//两种情况,这种是在当前点停留一段时间,在下一个能通过的时间段通过 return s[i]+vv; if(flag&&s[i]<=t&&s[i+1]>=t+vv)//到达这个点的时候刚好可以使用这条边 return t+vv; } return INF;//如果不能使用这条边,返回INF}void bellman(){ fill(d,d+n+1,INF); d[st]=0; int i,j; for(i=1;i<n;i++){ bool ok=true; for(j=0;j<edge.size();j++){ int may=allow(d[edge[j].st],j,edge[j].v);//用allow函数判断当前是否能够使用这条边 if(d[edge[j].to]>may){ d[edge[j].to]=may; ok=false; } } if(ok)break; } if(d[ed]==INF)printf("*\n"); else printf("%d\n",d[ed]);}int main(){// freopen("D://input.txt","r",stdin); while(scanf("%d",&n)!=EOF&&n){ scanf("%d%d%d",&m,&st,&ed); getchar(); edge.clear(); while(m--){ int a,b,c,x;string temp; getline(cin,temp);//读取字符串 stringstream ss(temp);//stringstream ss>>a;ss>>b;ss>>c;//输入起点,终点,权值 edge.push_back(Edge(a,b,c)); int id=edge.size()-1; edge[id].time.push_back(0);//在时间段的前后分别加上0和INF,操作起来比较方便 while(ss>>x)edge[id].time.push_back(x); edge[id].time.push_back(INF); edge.push_back(Edge(b,a,c)); id++;//无向边,所以反方向的边也要加上 for(int i=0;i<edge[id-1].time.size();i++) edge[id].time.push_back(edge[id-1].time[i]); } if(st==ed){printf("0\n");continue;} bellman(); } return 0;}
0 0
- POJ 1613/ZOJ 1791 Cave Raider(bellman-ford)
- POJ 1613 Cave Raider
- POJ-1613 Cave Raider
- poj 1613 Cave Raider
- poj 1613 Cave Raider (SPFA)
- poj 1613 Cave Raider 最短路
- ZOJ 1544 / POJ 1860 Currency Exchange(bellman-ford)
- zoj 1544 || poj 1860 Currency Exchange(Bellman-ford)
- poj-3259 bellman-ford
- poj 3259 bellman-ford
- poj 1860 bellman-ford
- poj 2240 bellman-ford
- poj 1847 bellman-ford
- poj 1860 Bellman-Ford
- poj 1860 (bellman-ford)
- poj 2240 Bellman-ford
- poj 1860 Bellman-Ford
- poj 3259 bellman-ford算法
- 小马哥------高仿htc m8 TB03型号刷机拆机主板图与开机识别图 精仿系列机型 分移动版与联通版
- gradle eclipse下构建ssh2项目
- Python __getattr__与__setattr__使用方法
- Group Anagrams
- 第一个Web前端
- POJ 1613/ZOJ 1791 Cave Raider(bellman-ford)
- 3d打印舵机零件
- bootchartd简介
- win7的系统怎么把屏幕颜色设置成保护眼睛的绿色???
- 负边距在布局中的使用
- 从头认识java-9.11 Queue
- linux下proc里关于磁盘性能的参数
- Mysql学习日记
- java基础 7种反转方法 charAt()等方法