poj 2267 From Dusk till Dawn or: Vladimir the Vampire

52 篇文章 0 订阅
From Dusk till Dawn or: Vladimir the Vampire
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 1135 Accepted: 354

Description

Vladimir has white skin, very long teeth and is 600 years old, but this is no problem because Vladimir is a vampire. 
Vladimir has never had any problems with being a vampire. In fact, he is a very successful doctor who always takes the night shift and so has made many friends among his colleagues. He has a very impressive trick which he shows at dinner partys: He can tell tell blood group by taste. 
Vladimir loves to travel, but being a vampire he has to overcome three problems. 
  • First, he can only travel by train because he has to take his coffin with him. (On the up side he can always travel first class because he has invested a lot of money in long term stocks.) 
  • Second, he can only travel from dusk till dawn, namely from 6 pm to 6 am. During the day he has to stay inside a train station. 
  • Third, he has to take something to eat with him. He needs one litre of blood per day, which he drinks at noon (12:00) inside his coffin.

You should help Vladimir to find the shortest route between two given cities, so that he can travel with the minimum amount of blood. (If he takes too much with him, people will ask funny questions like "What do you do with all that blood?")

Input

The first line of the input will contain a single number telling you the number of test cases. 
Each test case specification begins with a single number telling you how many route specifications follow. 
Each route specification consists of the names of two cities, the departure time from city one and the total travelling time. The times are in hours. Note that Vladimir can't use routes departing earlier than 18:00 or arriving later than 6:00. 
There will be at most 100 cities and less than 1000 connections. No route takes less than one hour and more than 24 hours. (Note that Vladimir can use only routes with a maximum of 12 hours travel time (from dusk till dawn).) All city names are shorter than 32 characters. 
The last line contains two city names. The first is Vladimir's start city, the second is Vladimir's destination.

Output

For each test case you should output the number of the test case followed by "Vladimir needs # litre(s) of blood." or "There is no route Vladimir can take."

Sample Input

2
3
Ulm Muenchen 17 2
Ulm Muenchen 19 12
Ulm Muenchen 5 2
Ulm Muenchen
10
Lugoj Sibiu 12 6
Lugoj Sibiu 18 6
Lugoj Sibiu 24 5
Lugoj Medias 22 8
Lugoj Medias 18 8
Lugoj Reghin 17 4
Sibiu Reghin 19 9
Sibiu Medias 20 3
Reghin Medias 20 4
Reghin Bacau 24 6
Lugoj Bacau

Sample Output

Test Case 1.
There is no route Vladimir can take.
Test Case 2.
Vladimir needs 2 litre(s) of blood.

Hint

The departure time maybe greater than 24.

Source

非常非常坑爹的题......有三个地方需要注意,唉太恶心了。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <map>
using namespace std;
const int maxv=1005;
const int maxe=1000005;
const int oo=1000000000;
int flow[maxe],to[maxe],next[maxe];
int head[maxv],dis[maxv],r[maxv],t[maxv];
int edge,m,start,end,sum;
string str1,str2;
struct Train
{
    int s,t,u,v;
} data[maxv];
bool vis[maxv];
queue<int>q;
inline void add(int u,int v,int c)
{
    to[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++;
}
void spfa()
{
    int v,i;
    while(!q.empty()) q.pop();
    memset(vis,0,sizeof(vis));
    for(i=1; i<sum; i++)
    {
        if(data[i].u==start)
        {
            vis[i]=1;
            dis[i]=0;
            q.push(i);
        }
        else dis[i]=oo;
    }
    while(!q.empty())
    {
        int tmp=q.front();
        q.pop();
        for(i=head[tmp]; ~i; i=next[i])
            if(dis[tmp]+flow[i]<dis[v=to[i]])
            {
                dis[v]=dis[tmp]+flow[i];
                if(!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        vis[tmp]=false;
    }
}
int main()
{
    int id,m,b,e,u,v,i,j,c,ca;
    cin>>ca;
    c=1;
    while(ca--)
    {
        cin>>m;
        edge=0;
        memset(head,-1,sizeof(head));
        id=sum=1;
        map<string,int>city;
        while(m--)
        {
            cin>>str1>>str2>>b>>e;
            if(!city[str1]) city[str1]=id++;
            if(!city[str2]) city[str2]=id++;
            u=city[str1],v=city[str2];
            b%=24;
            if((b>=18&&(b+e)<=30)||(b<=6&&(b+e)<=6)) //注意有效车次的判断
            {
                e=(b+e)%24;
                data[sum].u=u,data[sum].v=v;
                data[sum].s=b,data[sum++].t=e;
            }
        }
        cin>>str1>>str2;
        printf("Test Case %d.\n",c++);
        start=city[str1],end=city[str2];
        if(start==end) //特判
        {
            puts("Vladimir needs 0 litre(s) of blood.");
            continue;
        }
        if(start==0||end==0)
        {
            puts("There is no route Vladimir can take.");
            continue;
        }
        for(i=1; i<sum; i++)
        {
            for(j=1; j<sum; j++)
                if(data[i].v==data[j].u)
                {
                    if((data[j].s<data[i].t&&((data[j].s>=18&&data[i].t>=18)||(data[j].s<=6&&data[i].t<=6)))||(data[j].s>=18&&data[i].t<=6)) //注意花费的判断
                        add(i,j,1);
                    else add(i,j,0);
                }
        }
        spfa();
        int res=oo;
        for(i=1; i<sum; i++)
            if(res>dis[i]&&data[i].v==end) res=dis[i];
        if(res<oo) printf("Vladimir needs %d litre(s) of blood.\n",res);
        else puts("There is no route Vladimir can take.");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值