UVa1048 Low Cost Air Travel--最短路

很好的一道题呀

思路

状态\(d(i,j)\)表示已经经过了行程单中的\(i\)个城市,目前在城市\(j\)的最小代价,直接建边跑最短路就行了
比如机票为\(ACBD\),行程单为\(CD\),那么对于\((0,A)\),连向\((1,C)\),\((1,B)\),\((2,D)\)
有两个需要注意的地方
1.起点为\((1,行程单的起点)\)
2.城市编号很大,要离散化
以下是代码,离散化用\(map\)完成

#include <algorithm>
#include  <iostream>
#include   <cstdlib>
#include   <cstring>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <cmath>
#include     <ctime>
#include     <queue>
#include       <map>
#include       <set>

using namespace std;

#define ull unsigned long long
#define pii pair<int, int>
#define uint unsigned int
#define mii map<int, int>
#define lbd lower_bound
#define ubd upper_bound
#define INF 0x3f3f3f3f
#define IINF 0x3f3f3f3f3f3f3f3fLL
#define DEF 0x8f8f8f8f
#define DDEF 0x8f8f8f8f8f8f8f8fLL
#define vi vector<int>
#define ll long long
#define mp make_pair
#define pb push_back
#define re register
#define il inline

#define N 10000

struct Edge {
  int next, from, to, w, id;
}e[2000000];

int ticketCnt, routeCnt, nodeCnt, cityCnt;
int price[250], cities[250];
vi tickets[250];
map<pii, int> nodeId;
mii cityId;
pii originNode[N+5];
int head[N+5], eid;
int d[N+5], pre[N+5];
bool inq[N+5];
int stk[N+5], tp;
queue<int> q;

void addEdge(int u, int v, int w, int id) {
  e[++eid] = Edge{head[u], u, v, w, id};
  head[u] = eid;
}

void spfa() {
  memset(d, 0x3f, sizeof d);
  memset(inq, 0, sizeof inq);
  memset(pre, 0, sizeof pre);
  int S = nodeId[mp(1, cities[1])];
  d[S] = 0;
  q.push(S);
  while(!q.empty()) {
    int u = q.front(); q.pop();
    inq[u] = 0;
    for(int i = head[u]; i; i = e[i].next) {
      int v = e[i].to, w = e[i].w;
      if(d[v] > d[u]+w) {
        d[v] = d[u]+w;
        pre[v] = i;
        if(!inq[v]) inq[v] = 1, q.push(v);
      }
    }
  }
}

void mark(int u) {
  if(!pre[u]) return ;
  stk[++tp] = e[pre[u]].id;
  mark(e[pre[u]].from);
}

int main() {
  int kase = 0;
  while(~scanf("%d", &ticketCnt) && ticketCnt) {
    ++kase;
    nodeCnt = cityCnt = 0;
    nodeId.clear();
    cityId.clear();
    for(int i = 1, cnt; i <= ticketCnt; ++i) {
      scanf("%d%d", &price[i], &cnt);
      tickets[i].clear();
      for(int j = 1, x; j <= cnt; ++j) {
        scanf("%d", &x);
        if(!cityId.count(x)) cityId[x] = ++cityCnt;
        tickets[i].pb(cityId[x]);
      }
    }
    scanf("%d", &routeCnt);
    for(int t = 1, len; t <= routeCnt; ++t) {
      memset(head, 0, sizeof head);
      eid = 0;
      scanf("%d", &len);
      for(int c = 1; c <= len; ++c) {
        scanf("%d", &cities[c]);
        if(!cityId.count(cities[c])) cityId[cities[c]] = ++cityCnt;
        cities[c] = cityId[cities[c]];
      }
      for(int ticket = 1; ticket <= ticketCnt; ++ticket) {
        for(int i = cities[1] == tickets[ticket][0]; i <= len; ++i) {
          int cnt = i;
          pii cur = mp(i, tickets[ticket][0]);
          if(!nodeId.count(cur)) nodeId[cur] = ++nodeCnt, originNode[nodeCnt] = cur;
          for(int j = 1; j < tickets[ticket].size(); ++j) {
            if(cnt+1 <= len && cities[cnt+1] == tickets[ticket][j]) cnt++;
            pii newState = mp(cnt, tickets[ticket][j]);
            if(!nodeId.count(newState)) nodeId[newState] = ++nodeCnt, originNode[nodeCnt] = newState;
            addEdge(nodeId[cur], nodeId[newState], price[ticket], ticket);
          }
        }
      }
      spfa();
      printf("Case %d, Trip %d: Cost = %d\n", kase, t, d[nodeId[mp(len, cities[len])]]);
      printf("  Tickets used: ");
      tp = 0;
      mark(nodeId[mp(len, cities[len])]);
      for(int i = tp; i > 1; --i) printf("%d ", stk[i]);
      printf("%d\n", stk[1]);
    }
  }
  return 0;
}

原文地址:https://www.cnblogs.com/dummyummy/p/10823762.html

时间: 2024-11-09 01:19:36

UVa1048 Low Cost Air Travel--最短路的相关文章

UVA 1048 - Low Cost Air Travel(最短路)

UVA 1048 - Low Cost Air Travel 题目链接 题意:给定一些联票,在给定一些行程,要求这些行程的最小代价 思路:最短路,一张联票对应几个城市就拆成多少条边,结点表示的是当前完成形成i,在城市j的状态,这样去进行最短路,注意这题有坑点,就是城市编号可能很大,所以进行各种hash 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #in

On Imitation monkey the assignment is usually to carry a variety of major model low cost diesel-engined wristwatches

This wristwatches are made to glimpse very much like the genuine wristwatches in order to retain each of the efficiency. On Imitation monkey the assignment is usually to carry a variety of major model low cost diesel watches outlet within just one ro

HDU 4885 TIANKENG’s travel 最短路

判断是否共线用map记录下斜率: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include<algorithm> #include<math.h> #include<map> using namespace std; #define N 1022 const int INF = 1<<30-1;

HDU 1385 Minimum Transport Cost(Floyd 最短路 打印路径)

HDU 1385 大意: 有N个城市,然后直接给出这些城市之间的邻接矩阵,矩阵中-1代表那两个城市无道路相连,其他值代表路径长度. 如果一辆汽车经过某个城市,必须要交一定的钱(可能是过路费). 现在要从a城到b城,花费为路径长度之和,再加上除起点与终点外所有城市的过路费之和. 求最小花费,如果有多条路经符合,则输出字典序最小的路径. 思路: Floyd求最短路,打印路径即可. 1 /*--------------------------------------------------------

Impublished using a low cost cheap ghd straighteners australia

Impublished using a low cost cheap ghd straighteners australia conventional typical standard traditional in wide quantities of prints at only one reach. Advise your kids to mix the newspaper publishing when that like. Plenty of are saying it was even

Low cost diesel-engined wristwatches despite the fact that invest in whatever you idea seemed to be a legitimate dealership inside of a shopping mall

This activities, even so, are for various generations witout a doubt since they are very appropriate. However the activities usually are mailed by means of Switzerland corporations ETA in addition to Valjoux, there're improved with Chronome trieworkh

Travel(最短路)

Travel The country frog lives in has nn towns which are conveniently numbered by 1,2,…,n1,2,…,n. Among n(n−1)2n(n−1)2 pairs of towns, mm of them are connected by bidirectional highway, which needs aa minutes to travel. The other pairs are connected b

HDU 1385 Minimum Transport Cost (字典序打印最短路)

题意  给你一个无向图的邻接矩阵  和途径每个点需要的额外花费首尾没有额外花费  求图中某两点之间的最短路并打印字典序最小路径 要求多组点之间的就用floyd咯  打印路径也比较方便  nex[i][j]表示从i点到j点最短路的第一个途经点  那么如果路径中加入一个节点k后 nex[i][j]应该更新为nex[i][k]  因为要途径k了 #include<cstdio> #include<cstring> using namespace std; const int N = 10

Minimum Transport Cost Floyd 输出最短路

These are N cities in Spring country. Between each pair of cities there may be one transportation track or none. Now there is some cargo that should be delivered from one city to another. The transportation fee consists of two parts: The cost of the