大白书 P341这题说的是给了NT种飞机票,给了价钱和整个途径,给了nI条要旅游的路线。使用飞机票都必须从头第一站开始坐,可以再这个路径上的任何一点下飞机一但下飞机了就不能再上飞机,只能重新买票,对于每张票使用的状态有经过了这个路途的前i个点使用它,那么点就有,n*len(n为城市编号,为旅途所经过的所有点的个数),每张票在已经走完第一个点使用,第二个点,第三个点使用。。。最后从经过第一个点的旅途开始地方跑最长路,直到跑了len 旅途结束的点。

// LA3561 Low Cost Air Travel
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std; const int INF = ;
const int maxn = + ; struct Edge {
int from, to, dist, val;
}; struct HeapNode {
int d, u;
bool operator < (const HeapNode& rhs) const {
return d > rhs.d;
}
}; struct Dijkstra {
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
bool done[maxn]; // 是否已永久标号
int d[maxn]; // s到各个点的距离
int p[maxn]; // 最短路中的上一条弧 void init(int n) {
this->n = n;
for(int i = ; i < n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int dist, int val) {
edges.push_back((Edge){from, to, dist, val});
m = edges.size();
G[from].push_back(m-);
} void dijkstra(int s) {
priority_queue<HeapNode> Q;
for(int i = ; i < n; i++) d[i] = INF;
d[s] = ;
memset(done, , sizeof(done));
Q.push((HeapNode){, s});
while(!Q.empty()) {
HeapNode x = Q.top(); Q.pop();
int u = x.u;
if(done[u]) continue;
done[u] = true;
for(int i = ; i < G[u].size(); i++) {
Edge& e = edges[G[u][i]];
if(d[e.to] > d[u] + e.dist) {
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push((HeapNode){d[e.to], e.to});
}
}
}
} vector<int> GetShortestPath(int s, int t) {
vector<int> path;
while(t != s) {
path.push_back(edges[p[t]].val);
t = edges[p[t]].from;
}
reverse(path.begin(), path.end());
return path;
}
}; //////// 题目相关
#include<map> int n_cities;
map<int,int> city_id; int ID(int city) {
if(city_id.count(city)) return city_id[city];
city_id[city] = n_cities++;
return n_cities-;
} int ID(int visited, int cur) { return (visited-) * n_cities + cur; } const int maxnt = ;
int cost[maxnt];
vector<int> cities[maxnt], iti; Dijkstra solver; int main() {
int NT, NI, x, len, kase = ;
while(scanf("%d", &NT) == && NT) {
n_cities = ;
city_id.clear();
for(int i = ; i < NT; i++) {
cities[i].clear();
scanf("%d%d", &cost[i], &len);
while(len--) { scanf("%d", &x); cities[i].push_back(ID(x)); }
}
scanf("%d", &NI);
kase++;
for(int trip = ; trip <= NI; trip++) {
iti.clear();
scanf("%d", &len);
for(int i = ; i < len; i++) { scanf("%d", &x); iti.push_back(ID(x)); } solver.init(n_cities * len);
for(int ticket = ; ticket < NT; ticket++)
for(int visited = ; visited < len; visited++) {
int cur = cities[ticket][]; // 当前状态为(visited, cur)
int next = visited; // 下一个需要访问的城市在iti中的下标
for(int leg = ; leg < cities[ticket].size(); leg++) { // 使用前leg段
if(cities[ticket][leg] == iti[next]) next++; // 行程上多经过一个城市
solver.AddEdge(ID(visited, cur), ID(next, cities[ticket][leg]), cost[ticket], ticket+);
if(next == len) break; // 行程单已经走完
}
}
int src = ID(, iti[]), dest = ID(len, iti[len-]);
solver.dijkstra(src);
printf("Case %d, Trip %d: Cost = %d\n", kase, trip, solver.d[dest]);
printf(" Tickets used:");
vector<int> path = solver.GetShortestPath(src, dest);
for(int i = ; i < path.size(); i++) printf(" %d", path[i]);
printf("\n");
}
}
return ;
}

最新文章

  1. WinForm登陆:窗体间的数据传递
  2. .NET学习之路----我对P/Invoke技术的理解(一)
  3. hdu 1425 sort 解题报告
  4. [vijos P1034] 家族
  5. asp.net常用字符串函数
  6. JSONP(处理跨域问题)
  7. keepalived+haproxy-部署高可用负载均衡
  8. Paxos算法(转)
  9. CentOS使用sendmail发送邮件
  10. net开源cms系统
  11. 安卓Activity组件
  12. java 多维数组遍历
  13. 谈一谈CloudBlog的系统架构
  14. C语言博客作业04--数组
  15. 我写的Java相关的文章
  16. css3 实现波浪(wave)效果
  17. 通过http URL 获取图片流 转为字节数组
  18. Linux内核(1) - Kernel地图:Kconfig与Makefile
  19. 关于Mysql数据库进行多表查询时设计编程思想
  20. codeforces Round#429 (Div2)

热门文章

  1. x64dbg使用心得
  2. Thinkphp 图形验证码无法显示
  3. synchronized同步方法
  4. webpack中,css中打包背景图,路径报错
  5. 1.执行环境判断 window 或 self
  6. eclipse启动报错 Problems occurred when invoking code from plug-in: &quot;org.eclipse.jface&quot;
  7. ajax跨域终极解决办法!
  8. 一键搞定JavaEE应用,JRE+Tomcat+Mysql-JaveEE绿色运行环境JTM0.9版 (转载)
  9. Xshell配置ssh免密码登录-密钥公钥(Public key)
  10. [ASP.NET]从Request.Url获取根网址的最简单方法