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...

POJ3259—Bellman-Ford算法实现

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

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

思路: 对最短路的思想都深刻了解就能用求最短的思想求最长。这道题可以用好几种方法。

Poj 1860 Currency Exchange(Bellman-Ford,SPFA解单源最短路径问题)

一、题意          有多个货币交易点,每个只能互换两种货币,兑换的汇率不同,并收取相应的手续费。有N中货币,假定你拥有第S中,数量为V。现有M个兑换的。问你能不能通过兑换操作使你最后拥有的S币...

POJ 1860 Currency Exchange(Bellman-Ford判断最长路是否含有正环)

题目链接:kuangbin带你飞 专题四 最短路练习 E - Currency Exchange题意 有n种货币,你含有num面额的其中一种货币。 给定m种交易明细,即货币a和b之间的手续费...

【POJ 3259】Wormholes(最短路SPFA/Bellman_Ford)

DescriptionWhile exploring his many farms, Farmer John has discovered a number of amazing wormholes....

poj1716(差分约束+Bellman_Ford)

题目链接:http://poj.org/problem?id=1716        题目意思:有n个区间[a,b],现在要求寻找一个最短序列,要求该序列中至少有两个数字出现在所给n个区间的每个区间...

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

poj-2240-Arbitrage(Bellman-ford算法练习 + Floyd算法练习)
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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