题意:

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

思路:

(1)简单易操作方法:既然第二个集合的边只能有1条,就穷举下这些边,可能的边集进行求最短路,同时记录3个答案。复杂度是O(m*k)。

(2)时间复杂度低:不妨先求从s到每个其他点的距离d1[i],再求e到其他每个点的距离d2[i],接下来穷举第二个集合中的每条边u-v,那么最短距离为d1[u]+dis[u][v]+d2[v],注意边是无向的。麻烦在记录路径而已,还是挺容易操作的。复杂度是O(2m+k)。

下面是第一种方法的代码:

 #include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=;
int n, m, k;
vector<int> vect[N];
int edge_cnt;
struct node
{
int from, to, dis, tag;
node(){};
node(int from,int to,int dis,int tag):from(from),to(to),dis(dis),tag(tag){};
}edge[N*]; void add_node(int from,int to,int dis,int tag)
{
edge[edge_cnt]=node(from,to,dis,tag);
vect[from].push_back(edge_cnt++);
} int tag[N], dist[N], vis[N], path[N];
int dijkstra(int s,int e)
{
memset(dist,0x7f,sizeof(dist));
memset(tag,,sizeof(tag));
memset(vis,,sizeof(vis));
memset(path,,sizeof(path)); priority_queue<pii,vector<pii>,greater<pii> > que;
que.push(make_pair(, s));
dist[s]=; while(!que.empty())
{
int x=que.top().second;
que.pop();
if(vis[x]) continue;
vis[x]=;
for(int i=; i<vect[x].size(); i++)
{
node e=edge[vect[x][i]];
if( e.tag> && dist[e.to]>dist[x]+e.dis )
{
dist[e.to]=dist[x]+e.dis;
path[e.to]=x;
if(e.tag==)
{
tag[e.to]=true; //到这个点用了快线
}
que.push( make_pair(dist[e.to],e.to) );
}
}
}
return dist[e];
} void cal(int s ,int e)
{
vector<int> ans;
int quick=, big=dijkstra(s,e), d=e;//先跑了一遍不用快线的 while( d )
{
ans.push_back(d);
d=path[d];
} for(int i=m*; i<(m+k)*; i+= ) //穷举每条可以用的快线
{
edge[i].tag=;
edge[i+].tag=; int dis=dijkstra(s,e);
if( dis<big )
{
big=dis;
ans.clear();
int ed=e, tmp=;
while( ed )
{
if( tag[ed] ) tmp=path[ed]; //有可能没有用到
ans.push_back(ed);
ed=path[ed];
}
quick=tmp;//如果没有用到,也会及时更新为0
}
edge[i].tag=;
edge[i+].tag=;
} reverse(ans.begin(),ans.end());
printf("%d",ans[]); //千万注意输出格式
for(int i=; i<ans.size(); i++) printf(" %d",ans[i]);
printf("\n"); if(quick) printf("%d\n",quick);
else puts("Ticket Not Used");//别忘了 printf("%d\n",big);
} int main()
{
freopen("input.txt", "r", stdin);
int s=, e, a, b, c, ttt=;
while(~scanf("%d%d%d", &n, &s, &e))
{
if(ttt) printf("\n");ttt++;//格式啊!
edge_cnt=;
memset(edge,,sizeof(edge));
for(int i=; i<=n; i++) vect[i].clear();
scanf("%d",&m);
for(int i=; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
add_node(a,b,c,);
add_node(b,a,c,);
}
scanf("%d",&k);
for(int i=; i<k; i++)
{
scanf("%d%d%d",&a,&b,&c);
add_node(a,b,c,);
add_node(b,a,c,);
}
cal(s,e);
}
return ;
}

AC代码

UVA 11374 Airport Express 机场快线(单源最短路,dijkstra,变形)的更多相关文章

  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预处理 )

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

  3. UVA 11374 Airport Express (最短路)

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

  4. 利用分支限界法求解单源最短路(Dijkstra)问题

    分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分 ...

  5. 【算法】单源最短路——Dijkstra

    对于固定起点的最短路算法,我们称之为单源最短路算法.单源最短路算法很多,最常见的就是dijkstra算法. dijkstra主要用的是一种贪心的思想,就是说如果i...s...t...j是最短路,那么 ...

  6. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 C.星球游戏 (单源最短路,Dijkstra)

    题意:有\(n\)个点,\(m\)条双向边,两个方向的权值都是相等的,可以从\(A\)中的某个点出发走到\(B\)中的某个点,求所有路径中的最短距离,如果A和B中没有点联通,则输出\(-1\). 题解 ...

  7. 洛谷 P5837 [USACO19DEC]Milk Pumping G (单源最短路,dijkstra)

    题意:有一\(n\)个点,\(m\)条边的双向图,每条边都有花费和流量,求从\(1\)~\(n\)的路径中,求\(max\frac{min(f)}{\sum c}\). 题解:对于c,一定是单源最短路 ...

  8. UVA 11374 Airport Express SPFA||dijkstra

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

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

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

随机推荐

  1. Wmware桥接网络虚拟机无法上网的问题

    之前装好的一个虚拟机,安装到本地的Wmware workstation的时候,发现无法上网. 虚拟机使用的是桥接模式:一开始怀疑IP被占用,修改后发现不起作用.    排查所有的网络配置,发现都没有问 ...

  2. Linux 命令整理 —— 用户管理

    Linux用户管理以读.写.执行动作为权限,以用户组为单位,限制用户行为.对于文件的的操作,可以限制读.写.执行中的哪一种,也可以限制文件所有者.组用户.组外用户相应的权限. 所以,要建立用户,最好先 ...

  3. jQuery中的&& ||

    jQuery1.2.6 clean方法中有这么一段第一眼看去会让人晕掉的方法.完全不知其所言. “||, && 可以这样用?”,“这段东西最终返回的是个什么对象啊?” // Trim ...

  4. springMVC 简单事例

    本帖最后由 悲观主义者一枚 于 2015-1-31 17:55 编辑 使用SpringMvc开发Android WebService入门教程1.首先大家先创建一个JavaWeb项目2.然后加入Spri ...

  5. ssh 内在溢出

    相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题,这个问题曾困扰了我很长时间,随着解决各类问题经验的积累以及对问题根源的探索,终于有了一个比较深入的认识. 在解决j ...

  6. HDU1251 统计难题 Trie树

    题目很水,但毕竟是自己第一道的Trie,所以还是发一下吧.Trie的更多的应用慢慢学,AC自动机什么的也慢慢学.... #include<iostream> #include<cst ...

  7. 可持久化trie 学习总结

    QAQ 以前一直觉得可持久化trie很难,今天强行写了一发觉得还是蛮简单的嘛 自己的模板是自己手写的,写了几道题目并没有出过错误 THUSC的第二题的解法五貌似就是可持久化trie,时间复杂度O(60 ...

  8. lintcode :Invert Binary Tree 翻转二叉树

    题目: 翻转二叉树 翻转一棵二叉树 样例 1 1 / \ / \ 2 3 => 3 2 / \ 4 4 挑战 递归固然可行,能否写个非递归的? 解题: 递归比较简单,非递归待补充 Java程序: ...

  9. Mysql 分页语句Limit用法

    转载自:http://qimo601.iteye.com/blog/1634748 1.Mysql的limit用法 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用 ...

  10. sql的内连接 左外连接 右外连接 全外连接等连接查询的关系图

    经常会用到的,下面用图来表示各个连接