最短路。

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

当加上一条边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. 把工程部署在tomcat的root路径下

    myeclipse可以右键工程:(eclipse也可以)选择properties->myeclipse->web:把web context-root改成:/然后在用myeclipse部署项 ...

  2. 剑指offer--面试题13

    题目:以O(1)的时间复杂度删除单链表中的某个节点 自己所写代码如下: //以O(1)时间删除链表节点 //要求:单向链表,头指针,待删节点指针 //链表节点 struct ListNode { in ...

  3. PHP之implode与explode函数讲解

    implode (PHP 4, PHP 5) implode — 将一个一维数组的值转化为字符串 说明¶ string implode ( string $glue , array $pieces ) ...

  4. iOS 沙盒购买,弹出“需要验证”,“继续登录”的问题?

    点击购买后,能弹出 确认购买的对话框, 您想以xxx的价格买一个xxx吗? [environment:sandbox] 点击确认购买后,弹出"需要验证" 点击继续,输入密码后.竟然 ...

  5. Python Requests模块讲解4

    高级用法 会话对象 请求与响应对象 Prepared Requests SSL证书验证 响应体内容工作流 保持活动状态(持久连接) 流式上传 块编码请求 POST Multiple Multipart ...

  6. POJ2406 Power Strings KMP算法

    给你一个串s,如果能找到一个子串a,连接n次变成它,就把这个串称为power string,即a^n=s,求最大的n. 用KMP来想,如果存在的话,那么我每次f[i]的时候退的步数应该是一样多的  譬 ...

  7. 【hadoop2.6.0】用C++ 编写mapreduce

    hadoop通过hadoop streaming 来实现用非Java语言写的mapreduce代码. 对于一个一点Java都不会的我来说,这真是个天大的好消息. 官网上hadoop streaming ...

  8. GET和POST的区别,就是明信片和信封的区别

  9. hdu 1452 Happy 2004

    因子和: 的因子是1,2,3,6; 6的因子和是 s(6)=1+2+3+6=12; 的因子是1,2,4,5,10,20; 20的因子和是 s(20)=1+2+4+5+10+20=42; 的因子是1,2 ...

  10. python url编码,解码

    >>> urllib.unquote('%E4%B8%BD%E6%B1%9F') >>> data '\xe4\xb8\xbd\xe6\xb1\x9f' >& ...