最短路。

把题目抽象一下:已知一张图,边上的权值表示长度。现在又有一些边,只能从其中选一条加入原图,使起点->终点的距离最小。

当加上一条边a->b,如果这条边更新了最短路,那么起点st->终点ed的最小距离=st->a  +  a->b  +b->ed 三个值的最短距离之和。于是正反求两次单元最短路。再将k条边遍历一遍就好了。

最近在改代码风格,写起来很别扭。。uva又挂了,最让我不理解的是http://www.cnblogs.com/arbitrary/archive/2013/02/06/2908099.html这个家伙的代码竟然能ac,问题是我稍微改一下就submission error,难道代码还能防盗= =

 #include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#define clr(a,x) memset(a,x,sizeof(a));
#define ref(i,a,b) for(int i=a;i<=b;i++)
using namespace std; const int MAXN=;
const int INF =; struct Edge{
int u,v,c;
}; struct Node{
int d,u;
bool operator <(const Node x)const {
return d>x.d;
}
}; struct Dij{
int n,m;
vector<Edge>edge;
vector<int>G[MAXN];
bool vis[MAXN];
int d[MAXN];
int p[MAXN]; void init(int n)
{
this->n=n;
ref(i,,n-)G[i].clear();
edge.clear();
} void add(int u,int v,int c)
{
edge.push_back((Edge){u,v,c});
m=edge.size();
G[u].push_back(m-);
} void dij(int st)
{
priority_queue<Node>q;
ref(i,,n-)d[i]=(i==st)?:INF;
clr(vis,);
q.push((Node){,st});
while(!q.empty())
{
Node x=q.top();
q.pop();
int u=x.u;
if(vis[u])
continue;
vis[u]=true;
ref(i,,G[u].size()-){
Edge e=edge[G[u][i]];
if(d[e.v]>d[u]+e.c){
d[e.v]=d[u]+e.c;
p[e.v]=G[u][i];
q.push((Node){d[e.v],e.v});
}
}
}
}
}; Dij solver;
int d1[MAXN],d2[MAXN];
int p[MAXN]; int main()
{
int cnt=;
int n,m,k,st,ed;
while(~scanf("%d%d%d",&n,&st,&ed))
{
if(cnt++)
puts(""); st--;ed--;
solver.init(n); int u,v,c;
scanf("%d",&m);
ref(i,,m-){
scanf("%d%d%d",&u,&v,&c);
u--;v--;
solver.add(u,v,c);
solver.add(v,u,c);
} solver.dij(st);
ref(i,,n-)
d1[i]=solver.d[i]; solver.dij(ed);
ref(i,,n-){
d2[i]=solver.d[i];
p[i]=solver.p[i];
}
p[ed]=-; scanf("%d",&k);
int s=d1[ed],a,b;
a=b=-;
ref(i,,k-){
scanf("%d%d%d",&u,&v,&c);
u--;v--;
if(s>d1[u]+c+d2[v]){
s=d1[u]+c+d2[v];
a=u;b=v;
}
if(s>d1[v]+c+d2[u]){
s=d1[v]+c+d2[u];
a=v;b=u;
}
} int flog=;
if(a==-){ //不乘商务车
int x=st; while(x!=ed)
{
if(!flog){printf("%d",x+);flog=;}
else printf(" %d",x+);
x=solver.edge[p[x]].u; //p[]中保存的是 u->v 这条边的序号
}
printf(" %d",ed+);
printf("\nTicket Not Used\n%d\n",s);
}else{ //乘坐商务车
int x=st;
while(x!=a)
{
if(!flog){printf("%d",x+);flog=;}
else printf(" %d",x+);
x=solver.edge[p[x]].u;
}
if(x!=st)printf(" %d",x+);
else printf("%d",x+);
x=b;
while(x!=ed)
{
printf(" %d",x+);
x=solver.edge[p[x]].u;
}
printf(" %d\n",ed+);
printf("%d\n%d\n",a+,s);
}
}
return ;
} /*
4 1 4
4
1 2 2
1 3 3
2 4 4
3 4 5
1
1 4 7 2 1 2
1
1 2 2
1
1 2 1
*/

UVA 11374 Airport Express(最短路)的更多相关文章

  1. UVA - 11374 - Airport Express(堆优化Dijkstra)

    Problem    UVA - 11374 - Airport Express Time Limit: 1000 mSec Problem Description In a small city c ...

  2. UVA - 11374 Airport Express (Dijkstra模板+枚举)

    Description Problem D: Airport Express In a small city called Iokh, a train service, Airport-Express ...

  3. UVA 11374 Airport Express SPFA||dijkstra

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  4. UVA 11374 Airport Express 机场快线(单源最短路,dijkstra,变形)

    题意: 给一幅图,要从s点要到e点,图中有两种无向边分别在两个集合中,第一个集合是可以无限次使用的,第二个集合中的边只能挑1条.问如何使距离最短?输出路径,用了第二个集合中的哪条边,最短距离. 思路: ...

  5. UVA 11374 Airport Express(枚举+最短路)

    枚举每条商业线<a, b>,设d[i]为起始点到每点的最短路,g[i]为终点到每点的最短路,ans便是min{d[a] + t[a, b] + g[b]}.注意下判断是否需要经过商业线.输 ...

  6. UVA 11374 Airport Express (最短路)

    题目只有一条路径会发生改变. 常见的思路,预处理出S和T的两个单源最短路,然后枚举商业线,商业线两端一定是选择到s和t的最短路. 路径输出可以在求最短路的同时保存pa数组得到一棵最短路树,也可以用di ...

  7. UVa 11374 - Airport Express ( dijkstra预处理 )

    起点和终点各做一次单源最短路, d1[i], d2[i]分别代表起点到i点的最短路和终点到i点的最短路,枚举商业线车票cost(a, b);  ans = min( d1[a] + cost(a, b ...

  8. 【uva11374】Airport Express 最短路

    题意: 在Iokh市中,机场快线是市民从市内去机场的首选交通工具.机场快线分为经济线和商业线两种,线路,速度和价钱都不同.你有一张商业线车票,可以坐一站商业线,而其他时候只能乘坐经济线.假设换乘时间忽 ...

  9. uva 11374 最短路+记录路径 dijkstra最短路模板

    UVA - 11374 Airport Express Time Limit:1000MS   Memory Limit:Unknown   64bit IO Format:%lld & %l ...

随机推荐

  1. angular-file-upload API angular文件上传插件

    官方例子 : http://nervgh.github.io/pages/angular-file-upload/examples/simple/ ===Directives=== nvFileSel ...

  2. Educational Codeforces Round 13 E. Another Sith Tournament 概率dp+状压

    题目链接: 题目 E. Another Sith Tournament time limit per test2.5 seconds memory limit per test256 megabyte ...

  3. 基于 Eclipse 平台的代码生成技术

    ------------------------------------------------------------------ 转自http://www.ibm.com/developerwor ...

  4. Windows 进程通信 之 DDE技术

    DDE (Dynamic Data Exchange,DDE)动态数据交换,是一种进程间通信机制,它最早是随着Windows由微软提出的.当前大部分软件仍旧支持DDE,但最近十年里微软已经停止发展DD ...

  5. POJ 3070 Fibonacci(矩阵快速幂)

    题目链接 题意 : 用矩阵相乘求斐波那契数的后四位. 思路 :基本上纯矩阵快速幂. #include <iostream> #include <cstring> #includ ...

  6. android 上下文菜单详解

    本文使用xml来创建上下文菜单 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:andr ...

  7. Ubuntu 启动栏添加eclipse图标

    sudo gedit /usr/share/applications/eclipse.desktop [Desktop Entry] Name=Eclipse Comment=c project ma ...

  8. MQTT客户端与服务代理的案列

    服务端,采用 Mosquitto 来转发分发消息. 客户端自己写. 服务端 启动 mosquitto (底下的命令是我自己放到环境变量里面的,通过alias 运行mosquitto) Ishallbe ...

  9. ORA-12560: TNS: 协议适配器错误 解决

    传统方法: 大多数网站都有记载三个方法解决 但是出现上述错误另一个原因: 刚刚安装的Oracle 里面的账户都是锁定的 需要解锁 见如下的Oracle11g安装过程 http://www.2cto.c ...

  10. Project Euler 81:Path sum: two ways 路径和:两个方向

    Path sum: two ways In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom ...