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

Cave Raider Time Limit: 1000MS   Memory Limit: 10000K Description Afkiyia is a ...

POJ 1613 Cave Raider

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

zoj 1544 || poj 1860 Currency Exchange(Bellman-ford)

我啊,自作聪明用dij先最短路,然后用bellman的判断负环判断 = =。。。结果WA得很惨。后来改成bellman-ford,党的那种 = =。。if( ( dis[x] - comm) * ra...

POJ - 3259 Wormholes解题报告(Bellman-Ford判断有向图中是否有负权环)

题目大意:一个有向图,给你n个点,m条双向路径,以及t条虫洞。每条路径描述在两个点ab之间移动需要时间v。每条虫洞描述从a到b需要时间-v(类似于时空穿越)。现在就问你,一个人能否从某个点开始,通过若...

POJ1716—差分约束系统+Bellman-Ford算法 || SPFA算法的实现

题目看去有点难下手,如果学习了差分约束系统或是贪心算法会觉得很简单。 刚开始时用Bellman-Ford算法解,采用的是求最短路径,由于Bellman-Ford算法复杂度本身就高,再加上增设了m+1...

poj 3259 最短路判负环 spfa算法和Bellman_ford算法

题目:http://poj.org/problem?id=3259 题意: 有个人在一个图上旅行,当它从一点出发后,可能会经过一些虫洞边,然后时光倒流,回到原点,看到自己,看了好久样例一才看清题意...

[ACM] POJ 3259 Wormholes (bellman-ford最短路径,判断是否存在负权回路)

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29971   Acc...

poj_1860 Bellman-Ford算法的逆向应用

问题:货币兑换是否可以有增值 解法:
  • yeruby
  • yeruby
  • 2014年07月24日 10:20
  • 533

POJ3259—Bellman-Ford算法实现

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

poj 2240 Arbitrage(Bellman-Ford||Floyd)(中等)

思路: 对最短路的思想都深刻了解就能用求最短的思想求最长。这道题可以用好几种方法。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 1613/ZOJ 1791 Cave Raider(bellman-ford)
举报原因:
原因补充:

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