题意:

  给一幅图,要从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. 【转载】hadoop的版本问题

    免责声明:     本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除.     原文作者:阿笨猫      原文地址:http://www.cnblogs.com/xu ...

  2. 如何在Eclipse中配置Tomcat服务器

    之前使用MyEclipse来开发Web应用,可以在MyEclipse中配置服务器,配置完后,直接运行服务器即可,很方便. 最近切换到Eclipse开发环境,发现使用Tomcat的方式不太一样,因此在此 ...

  3. HDU3068 最长回文 Manacher算法

    Manacher算法是O(n)求最长回文子串的算法,其原理很多别的博客都有介绍,代码用的是clj模板里的,写的确实是异常的简洁,现在的我只能理解个大概,下面这个网址的介绍比较接近于这个模板,以后再好好 ...

  4. 黑马程序员-C#学习笔记

    ---------------------- ASP.Net+Android+IOS开发..Net培训.期待与您交流! ---------------------- C#学习笔记 1..NET/.do ...

  5. 深入浅出Java并发包—锁机制(一)

    前面我们看到了Lock和synchronized都能正常的保证数据的一致性(上文例子中执行的结果都是20000000),也看到了Lock的优势,那究竟他们是什么原理来保障的呢?今天我们就来探讨下Jav ...

  6. hdu1874 畅通工程续

    http://acm.hdu.edu.cn/showproblem.php?pid=1874 //标准最短路模板 //需要注意的是两点间可能有多组 //需要取最短的 #include<iostr ...

  7. PKUSC 模拟赛 day2 下午总结

    终于考完了,下午身体状况很不好,看来要锻炼身体了,不然以后ACM没准比赛到一半我就挂掉了 下午差点AK,有一道很简单的题我看错题面了所以没有A掉 第一题显然是非常丝薄的题目 我们很容易通过DP来O(n ...

  8. PKUSC 模拟赛 day1 上午总结

    思考了一下第二题,觉得有无数种乱搞做法 类似什么bitset压位,MCS染色之类奇怪的做法 然而都是玄学正确性或者玄学复杂度 先放题解把 第一题显然具有单调性,二分就可以啦 O(nlogn),貌似输出 ...

  9. HEOI2016游记

    DAY -1: 省选前集训因为某些事情感觉心情和状态异常的糟糕 坐在窗户上吹了半个小时的冷风之后觉得回家休息一段时间 (反正我家在保定,大不了我省选的时候直接去河北大学就好辣) 在家里颓了三天吧,想清 ...

  10. 两个List合并,过滤重复记录

    import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.I ...