UCF Local Programming Contest 2017 Multimodal Transport(建圖 + 最短路)

New methods of shipping goods have transformed the transportation industry and helped usher in an era of global commerce.  Nowadays, someone can click a few buttons and have an item leave a factory on the other side of the world and show up at their doorstep the next day.  To help accomplish this, there are a number of modes of transport within the shipping industry.  The four most common are: air, boat, rail and truck.     

Transportation companies tend to keep the mode of transport consistent throughout a packages journey (route/path).  However, when customers are not very time sensitive, often times the cheapest way to move a package from one location to another is to use more than one mode of transport.  One has to be careful, though, as additional costs are incurred when switching between transport modes within a city on the package path.   (Switching transport mode refers to a package leaving a city in a different mode than it arrived at the city, e.g., the package arrived by air and leaves by truck.)   

A new startup, KnightShip, has asked for your help in figuring out the cheapest way to ship packages when switching between transportation modes is acceptable. 

The Problem:   

Given the costs for various modes of transport between cities, and the cost of switching mode within a city, calculate the lowest cost to transport an item from an origin to a destination. 

The Input:   

The first input line contains a positive integer, n, indicating the number of test cases to process.  Each test case will contain multiple input lines.  The first line of each test case will contain an integer, c (2 ≤ c ≤ 400), representing the number of cities within the transportation network.  Each of the following c input lines contains two values: a string (1 to 20 uppercase letters, inclusive), representing the name of a city and an integer (between 1 and 1000, inclusive), representing the cost of changing the transport mode within that city.  

The city information for a test case is followed by the route information for the test case.  There will be an input line containing one integer, r (1 ≤ r ≤ 40000), representing the number of route segments in the network.  This will be followed by a listing of all route segments, one per line.  Each route segment will contain four values: p, q, representing two cities from the previous list, m, representing the transport mode (one of four values AIR, SEA, RAIL, TRUCK) for that route segment, and an integer v (1 ≤ v ≤ 1000), representing the cost to ship a package between the two cities (either direction).  Note that there may be no route segments for a particular transport mode.  There will be no duplicate city pair within a given mode of transport, but different transport modes (even all four modes) can exist between the same two cities. 

The last input line for a test case contains two distinct cities o and d which represent the origin and destination cities for which we want the minimum cost to ship a package.  Cities o and d are guaranteed to have a path (of finite cost) that exists between them.  Any mode of transport can be used to leave city o and any mode can be used to reach city d (they don’t necessarily need to match).  The transport mode can change in the intermediate stages as well.   

The Output:   

For each test case, output a single integer on a line by itself indicating the minimum cost to move a package from city o to city d.   

樣例輸入複製

2
4
ORLANDO 10
TAMPA 15
MIAMI 5
JACKSONVILLE 10
7
TAMPA JACKSONVILLE AIR 100
MIAMI TAMPA SEA 70
JACKSONVILLE MIAMI RAIL 45
ORLANDO JACKSONVILLE TRUCK 85
TAMPA ORLANDO RAIL 10
MIAMI JACKSONVILLE SEA 15
ORLANDO MIAMI TRUCK 15
JACKSONVILLE TAMPA
2
ORLANDO 15
TAMPA 10
3
ORLANDO TAMPA AIR 7
TAMPA ORLANDO TRUCK 3
ORLANDO TAMPA RAIL 19
ORLANDO TAMPA

樣例輸出複製

55
3

題意:

有 n 個城市,每個城市都有4種運輸方式,給出在每個城市轉換交通工具的費用和若干條邊,求最短路

思路:

將每個城市每種交通方式看作一個獨立的點,這樣就有4 * n個點,預處理出同一城市內轉換交通工具的費用。

寫的比較笨:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 2e3 + 5;

int n, tot, T, m;
int g[N][N];
int dis[N];
bool vis[N];
map<string, int>mp;

void add(string s, int cos)
{
    int a[4];
    mp[s + " AIR"] = ++tot;
    a[0] = tot;
    mp[s + " SEA"] = ++tot;
    a[1] = tot;
    mp[s + " RAIL"] = ++tot;
    a[2] = tot;
    mp[s + " TRUCK"] = ++tot;
    a[3] = tot;
    for(int i = 0; i < 4; ++i)
    {
        for(int j = i + 1; j < 4; ++j)
        {
            g[a[i]][a[j]] = g[a[j]][a[i]] = cos;
        }
    }
}

void dijk(int s)
{
    memset(vis, 0, sizeof(vis));
    for(int i = 1; i <= n; ++i)
    {
        dis[i] = g[s][i];
    }
    vis[s] = 1;
    dis[s] = 0;
    for(int i = 1; i <= n; ++i)
    {
        int minn = inf, pos;
        for(int j = 1; j <= n; ++j)
        {
            if(!vis[j] && minn > dis[j])
            {
                pos = j;
                minn = dis[j];
            }
        }
        vis[pos] = 1;
        for(int j = 1; j <= n; ++j)
        {
            if(!vis[j] && dis[j] > dis[pos] + g[pos][j])
            {
                dis[j] = dis[pos] + g[pos][j];
            }
        }
    }
}

int main()
{
    string s, t, a, b, k;
    int cos;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        for(int i = 1; i <= 4 * n; ++i)
        {
            g[i][i] = 0;
            for(int j = i + 1; j <= 4 * n; ++j)
            {
                g[i][j] = g[j][i] = inf;
            }
        }
        tot = 0;
        for(int i = 1; i <= n; ++i)
        {
            cin >> s >> cos;
            add(s, cos);
        }
        n *= 4;
        scanf("%d", &m);
        for(int i = 1; i <= m; ++i)
        {
            cin >> a >> b >> k >> cos;
            a += " " + k;
            b += " " + k;
            if(g[mp[a]][mp[b]] > cos)
            {
                g[mp[a]][mp[b]] = g[mp[b]][mp[a]] = cos;
            }
        }
        cin >> s >> t;
        int ans = inf;
        dijk(mp[s + " AIR"]);
        ans = min(ans, min(dis[mp[t + " AIR"]], min(dis[mp[t + " SEA"]], min(dis[mp[t + " RAIL"]], dis[mp[t + " TRUCK"]]))));
        dijk(mp[s + " SEA"]);
        ans = min(ans, min(dis[mp[t + " AIR"]], min(dis[mp[t + " SEA"]], min(dis[mp[t + " RAIL"]], dis[mp[t + " TRUCK"]]))));
        dijk(mp[s + " RAIL"]);
        ans = min(ans, min(dis[mp[t + " AIR"]], min(dis[mp[t + " SEA"]], min(dis[mp[t + " RAIL"]], dis[mp[t + " TRUCK"]]))));
        dijk(mp[s + " TRUCK"]);
        ans = min(ans, min(dis[mp[t + " AIR"]], min(dis[mp[t + " SEA"]], min(dis[mp[t + " RAIL"]], dis[mp[t + " TRUCK"]]))));
        cout<<ans<<'\n';
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章