hdu 2992 Hotel booking(spfa+floyd+地图)

hdu 2992 Hotel booking(spfa+floyd+map)

http://acm.hdu.edu.cn/showproblem.php?pid=2992

题意:运输公司要从初始城市运送货物到目的城市,共有n个城市,编号是1~n。出发点和目的地分别是1和n号城市。在这些城市中有h个免费客栈,司机一天最多能走10小时,晚上选择一个客栈休息。给出h个客栈所在的城市以及m个城市的连接情况,问最少需要的客栈数。


思路:把h个客栈看做点,编号为1~h,起点标号为0,终点标号为h+1,这样共h+2个点。spfa求任两个客栈之间的路程,若 <= 600,则建边(注意建边建的是客栈的编号,而不是城市编号,用map映射),权值为1。最后求0到h+1的最短路。


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
using namespace std;

const int INF = 0x3f3f3f3f;

struct node
{
    int u,v;
    int w;
};

map <int, int> mp;
vector <struct node> edge[10010];

int n,m,num;
int a[110];
int graph[110][110]; //映射后的图

void init()
{
    mp.clear();
    for(int i = 1; i <= n; i++)
        edge[i].clear();

    for(int i = 0; i <= num+2; i++)
    {
        for(int j = 0; j <= num+2; j++)
        {
            if(i == j) graph[i][j] = 0;
            else graph[i][j] = INF;
        }
    }
}

void spfa(int s)
{
    queue <int> que;
    int dis[10100];
	int inque[10100];
	
    while(!que.empty()) que.pop();
    memset(dis,INF,sizeof(dis));
    memset(inque,0,sizeof(inque));

    dis[s] = 0;
    inque[s] = 1;
    que.push(s);

    while(!que.empty())
    {
        int u = que.front();
        que.pop();
        inque[u] = 0;
        for(int i = 0; i < (int)edge[u].size(); i++)
        {
            int v = edge[u][i].v;
            if(dis[v] > dis[u] + edge[u][i].w)
            {
                dis[v] = dis[u] + edge[u][i].w;
                if(!inque[v])
                {
                    inque[v] = 1;
                    que.push(v);
                }
            }
        }
    }
    
    for(int i = 1; i <= n; i++)
    {
        if(dis[i] <= 600)
            graph[ mp[s] ][ mp[i] ] = 1;
    }
}

void floyd() //求0到h+1的最短路
{
    for(int k = 0; k <= num+1; k++)
    {
        for(int i = 0; i <= num+1; i++)
        {
            for(int j = 0; j <= num+1; j++)
            {
                if( graph[i][k] + graph[k][j] < graph[i][j])
                    graph[i][j] = graph[i][k] + graph[k][j];
            }
        }
    }
}

int main()
{
    while(~scanf("%d",&n) && n)
    {
        scanf("%d",&num);
        init();
        for(int i = 1; i <= num; i++)
        {
            scanf("%d",&a[i]);
            mp[ a[i] ] = i;
        }
        
        mp[1] = 0;
        mp[n] = num+1;
        a[0] = 1;
        a[num+1] = n;

        scanf("%d",&m);
        while(m--)
        {
            int u,v,w;
            scanf("%d %d %d",&u,&v,&w);
            edge[u].push_back((struct node) {u,v,w});
            edge[v].push_back((struct node) {v,u,w});
        }

        for(int i = 0; i <= num+1; i++)
            spfa( a[i] );

        floyd();

        if(graph[0][num+1] < INF)
            printf("%d\n",graph[0][num+1]-1);
        else printf("-1\n");
    }
    return 0;
}