加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ PKU 2267 图论 模拟 最短路

(2010-08-10 18:29:46)
标签:

poj

pku

2267

图论

模拟

最短路

it

分类: 图论

题目描述:

一个吸血鬼要从一个城市到另外一个城市,只能在晚上 6 点到早上 6 点之间出行(出发时间和到达时间都要在晚六点到早六点之间),其它时间则只能呆在车站,每天中午 12 点需要喝一升血。

给你许多火车路线的信息(起点,重点,开车时间,车运行时间)

还有你的起点和终点。

问你为了完成旅行它需要准备多少升血?

解题报告:

由于坐每趟火车不会消耗血(时间只能是晚上,而喝血要在中午),

所以消耗的血只能发生在两趟火车之间,即一趟火车结束到下一趟或者出发之间包括了中午12点。

那样,就以火车路线为点建立图,路线之间如果有中午,权值为1,否则为0.

求最短路。

几点注意:

1 有可能你的起点和终点一样,此时输出0.

2 有可能你的起点或者终点就没有出现在路线中,此时不可能。

代码如下:

#include<iostream>
#include<cstring>
#include<map>
#include<string>
#include<vector>
#include<cstdio>
using namespace std;
#define siz 1005
struct edge{int to, next, va;}e[1000000];
struct jeo{int from, to, sta, len, end;} x[siz];
int cnt, v[siz * siz], n, t, num, from, to, m, d[siz * siz], que[siz * 1000], vst[siz * siz];
void insert(int from, int to, int va)
{
    e[cnt].to = to, e[cnt].next = v[from], e[cnt].va = va;
    v[from] = cnt++;
}
map<string, int> hash;
string a, b;
int spfa()
{
    int head = 0, tail = 0;
    memset(vst, 0, sizeof(vst));
    for(int i = 0; i < m; i++)
        if (x[i].from == from)
        {
            d[i] = 0;
            que[tail++] = i;
            vst[i] = 1;
        }
        else d[i] = 0x7fffffff;
    while(head != tail)
    {
        int id = que[head++]; vst[id] = 0;
        if (head == 1000000) head = 0;
        int tmp = v[id];
        while(tmp != -1)
        {
            if (d[id] + e[tmp].va < d[e[tmp].to])
            {
                d[e[tmp].to] = d[id] + e[tmp].va;
                if (!vst[e[tmp].to])
                {
                    vst[e[tmp].to] = 1;
                    que[tail++] = e[tmp].to;
                    if (tail == 1000000) tail = 0;
                }
            }
            tmp = e[tmp].next;
        }
    }
    int ans = 0x7fffffff;
    for(int i = 0; i < m; i++)
        if (x[i].to == to && d[i] < ans) ans = d[i];
    if (ans == 0x7fffffff) return -1;
    return ans;
}
int main()
{
    scanf("%d", &t);
    for(int ca = 1; ca <= t; ca++)
    {
        scanf("%d", &n); hash.clear(); num = 1; m = 0;
        for(int i = 0; i < n; i++)
        {
            cin >> a >> b;scanf("%d%d", &x[m].sta, &x[m].len);
            x[m].sta %= 24;
            if (x[m].len <= 12 && (x[m].sta >= 18 || x[m].sta <= 6) && x[m].len <= ((30 - x[m].sta) % 24))
            {
                int tmp1 = hash[a]; if (tmp1 == 0) tmp1 = hash[a] = num++;
                int tmp2 = hash[b]; if (tmp2 == 0) tmp2 = hash[b] = num++;
                x[m].end = (x[m].sta + x[m].len) % 24;
                x[m].from = tmp1, x[m++].to = tmp2;
            }
        }
        cin >> a >> b;
        from = hash[a], to = hash[b];
        if (from == 0 || to == 0)
            printf("Test Case %d.\nThere is no route Vladimir can take.\n", ca);
        else
        {
            if (from == to)
            {
                printf("Test Case %d.\nVladimir needs 0 litre(s) of blood.\n", ca);
                continue;
            }
            memset(v, -1, sizeof(int) * (m)); cnt = 0;
            for(int i = 0; i < m; i++)
                for(int j = 0; j < m; j++)
                    if (x[i].to == x[j].from)
                        insert(i, j, ((x[j].sta + 24 - x[i].end) % 24) >= 12);
            int tmp = spfa();
            if (tmp == -1)
                printf("Test Case %d.\nThere is no route Vladimir can take.\n", ca);
            else
                printf("Test Case %d.\nVladimir needs %d litre(s) of blood.\n", ca, tmp);
        }
    }
    return 0;
}

 

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有