题意:

  给一幅图,要从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. 【POJ】【3164】Commond Network

    最小树形图 最小树形图模板题,朱-刘算法. 题解:http://blog.csdn.net/shuangde800/article/details/8039359 这位大神代码写的非常通俗易懂,而且这 ...

  2. 电脑问题交流QQ群

    各种电脑问题交流QQ群号 164853622 系统重装 系统恢复 系统出问题 电脑主页 修改 主页 搜狗 软件卸载 顽固 病毒 讨论

  3. C#三种定时器的实现

    http://www.coridc.com/archives/2253.html c#中提供了三种类型的计时器: 1.基于 Windows 的标准计时器(System.Windows.Forms.Ti ...

  4. sp_MSforeachtable使用方法 查看库中所有表的空间大小

    sp_MSforeachtable使用方法 1)说明系统存储过程sp_MSforeachtable和sp_MSforeachdb,是微软提供的两个不公开的存储过程,从ms sql 6.5开始.存放在S ...

  5. jQuery从主页面存取控制 iframe 中的元素,参数及方法

    从主页面上获取iframe下的某个对象,或使用iframe下的方法,或是获取iframe下某个doc元素,要求兼容各类浏览器,不仅仅ie; $(function() { $('#abgne_ifram ...

  6. 欧拉工程第63题:Powerful digit counts

    题目链接 The 5-digit number, 16807=75, is also a fifth power. Similarly, the 9-digit number, 134217728=8 ...

  7. 随机森林分类(Random Forest Classification)

    其实,之前就接触过随机森林,但仅仅是用来做分类和回归.最近,因为要实现一个idea,想到用随机森林做ensemble learning才具体的来看其理论知识.随机森林主要是用到决策树的理论,也就是用决 ...

  8. ibatis框架的sqlmapclient接口

    SqlMapClient,是iBatis中的重要接口,这个接口涉及到对SQL映射的执行和批处理. 现在,就先了解它的对query开头方法的定义. 首先是 queryForList 方法: //指定SQ ...

  9. pymongo 例子

    import pymongo class dbUtil(object): def __init__(self, tablename='functional_testing'): con = pymon ...

  10. c语言中static的用法

    1.static定义变量: 1).局部: a.静态局部变量在函数内部定义,生存期为整个源代码,但作用域与自动变量相同,只能在定义的函数里面使用.退出该函数后,虽然此变量还存在内存中,但不能使用. b. ...