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;
}
UVa1048 Low Cost Air Travel——最短路的更多相关文章
- SCU 4444: Travel(最短路)
Travel The country frog lives in has n towns which are conveniently numbered by 1,2,…,n . Among n(n− ...
- Travel(最短路)
Travel The country frog lives in has nn towns which are conveniently numbered by 1,2,…,n1,2,…,n. Amo ...
- [USACO09JAN]安全出行Safe Travel 最短路,并查集
题目描述 Gremlins have infested the farm. These nasty, ugly fairy-like creatures thwart the cows as each ...
- L147 Low Cost Study Has High Impact Results For Premature Babies
No one knows exactly why some babies are born prematurely(早产), but some of the smallest premature ba ...
- 【BZOJ1576】[Usaco2009 Jan]安全路经Travel 最短路+并查集
[BZOJ1576][Usaco2009 Jan]安全路经Travel Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, ...
- BZOJ1576: [Usaco2009 Jan]安全路经Travel(最短路 并查集)
题意 给你一张无向图,保证从1号点到每个点的最短路唯一.对于每个点求出删掉号点到它的最短路上的最后一条边(就是这条路径上与他自己相连的那条边)后1号点到它的最短路的长度 Sol emmm,考场上想了个 ...
- Minimum Transport Cost Floyd 输出最短路
These are N cities in Spring country. Between each pair of cities there may be one transportation tr ...
- uva 1048 最短路的建图 (巧,精品)
大白书 P341这题说的是给了NT种飞机票,给了价钱和整个途径,给了nI条要旅游的路线.使用飞机票都必须从头第一站开始坐,可以再这个路径上的任何一点下飞机一但下飞机了就不能再上飞机,只能重新买票,对于 ...
- 最短路+状态压缩dp(旅行商问题)hdu-4568-Hunter
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4568 题目大意: 给一个矩阵 n*m (n m<=200),方格里如果是0~9表示通过它时要花 ...
随机推荐
- kafka的offset相关知识
Offset存储模型 由于一个partition只能固定的交给一个消费者组中的一个消费者消费,因此Kafka保存offset时并不直接为每个消费者保存,而是以 groupid-topic-partit ...
- 【转贴】SMP、NUMA、MPP体系结构介绍
SMP.NUMA.MPP体系结构介绍 https://www.cnblogs.com/tcicy/p/10185783.html 从系统架构来看,目前的商用服务器大体可以分为三类,即对称多处理器结构 ...
- SpringBoot传参方式
地址传参 1.创建一个Action类 package com.lion.action; import org.springframework.stereotype.Controller; import ...
- Redis 学习笔记(篇十):Sentinel
Sentinel(哨兵)是 Redis 的高可用解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主 ...
- 对称加密、非对称加密、数字签名、数字证书、SSL是什么
非对称密钥加解密 对于一份数据,通过一种算法,基于传入的密钥(一串由数字或字符组成的字符串,也称key),将明文数据转换成了不可阅读的密文,这就是“加密”,同样的,密文到达目的地后,需要再以相应的算法 ...
- AC自动机fail树上dfs序建线段树+动态memset清空
题意:http://acm.hdu.edu.cn/showproblem.php?pid=4117 思路:https://blog.csdn.net/u013306830/article/detail ...
- Go语言操作NoSql
NSQ平台 NSQ是目前比较流行的一个分布式的消息队列,本文主要介绍了NSQ及Go语言如何操作NSQ. NSQ NSQ介绍 NSQ是Go语言编写的一个开源的实时分布式内存消息队列,其性能十分优异. N ...
- 【广搜】Knight Moves
题目描述 Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights fr ...
- 阿里云=>RHSA-2019:1884-中危: libssh2 安全更新
由于项目构建时间比较长,近期安全检查发现openssh有漏洞.所以要升级openssh到7.9p1版本.由于ssh用于远程连接,所以要谨慎操作. 建议生成环境要先做测试,之后再在生产环境升级. 1 前 ...
- iview表单验证数字
验证输入字符串必须为数字 html: <FormItem label="兑换积分:" prop="exchangeIntegral"> <In ...