POJ 1613/ZOJ 1791 Cave Raider(bellman-ford)

原创 2015年11月19日 22:30:48

链接:http://poj.org/problem?id=1613

这题被无向边坑了很久,wa了好多次,最后从有向边改成无向边就过了。

样例解释:


2 2 1 2
1 2 5 4 10 14 20 24 30
1 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;
}



版权声明:随意转载,转载声明出处~

POJ 1613 Cave Raider

SPFA过的。 虽然很麻烦,其实就是加上一个限制条件的最短路。 题意是说给你一些点,一些边,起点与终点。 然后这些边通过的时候需要花费时间,但是也有开关限制。 问你到达重点的最短路。(无向...
  • dongshimou
  • dongshimou
  • 2014年07月02日 17:16
  • 763

poj 1613 Cave Raider

Cave Raider Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 870   Acc...
  • u012866104
  • u012866104
  • 2014年09月10日 18:58
  • 340

poj 1613 Cave Raider (SPFA)

Cave Raider Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 744   Acc...
  • u010228612
  • u010228612
  • 2013年08月13日 12:26
  • 639

poj 1613 Cave Raider 最短路

很简单的最短路,只是加上了一定的限制条件。         首先读取时做下处理,把开放时间小于通行时间的去掉。         做最短路的时候判断好逻辑关系即可         注意,这题输入有...
  • czjxy881
  • czjxy881
  • 2013年05月15日 13:57
  • 671

(poj1.3.2)1791(构造法模拟)

/* * 1791_1.cpp * * Created on: 2013年10月6日 * Author: Administrator */ #include #include...
  • caihongshijie6
  • caihongshijie6
  • 2013年10月06日 15:15
  • 1061

poj-2240-Arbitrage(Bellman-ford算法练习 + Floyd算法练习)

poj-2240-Arbitrage(Bellman-ford算法练习 + Floyd算法练习)
  • sinat_34263473
  • sinat_34263473
  • 2016年08月08日 20:38
  • 873

POJ-1613 Cave Raider

Cave Raider Time Limit: 1000MS   Memory Limit: 10000K Description Afkiyia is a ...
  • u012325552
  • u012325552
  • 2014年08月13日 16:32
  • 764

POJ3259—Bellman-Ford算法实现

题目的大意是有F个农场,每个农场有N个牧场,M条双向路径,W个虫洞,虫洞是单向的,可以实现时间旅行,返回到以前某个时间。问从某个牧场出发,经过若干路径和虫洞,能否在没有离开出发地时回到出发地,见到自己...
  • sky1203850702
  • sky1203850702
  • 2012年08月15日 11:27
  • 734

poj2240 Bellman-ford最短路求最大回路

Arbitrage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17921   Accepted: 7571 ...
  • became_a_wolf
  • became_a_wolf
  • 2015年08月18日 15:40
  • 521

poj-3259 bellman-ford

题意: John的农场里N块地,M条路连接两块地,W个虫洞;路是双向的,虫洞是一条单向路,会在你离开之前把你传送到目的地, 就是当你过去的时候时间会倒退Ts。我们的任务是知道会不会在从某块地出发后...
  • zhang20072844
  • zhang20072844
  • 2012年07月22日 21:42
  • 933
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 1613/ZOJ 1791 Cave Raider(bellman-ford)
举报原因:
原因补充:

(最多只允许输入30个字)