SAMER08A - Almost Shortest Path

Finding the shortest path that goes from a starting point to a destination point given a set of points and route lengths connecting them is an already well known problem, and it's even part of our daily lives, as shortest path programs are widely available nowadays.

Most people usually like very much these applications as they make their lives easier. Well, maybe not that much easier.

Now that almost everyone can have access to GPS navigation devices able
to calculate shortest paths, most routes that form the shortest path
are getting slower because of heavy traffic. As most people try to
follow the same path, it's not worth it anymore to follow these
directions.

With this in his mind, your boss asks you to develop
a new application that only he will have access to, thus saving him
time whenever he has a meeting or any urgent event. He asks you that the
program must answer not the shortest path, but the almost shortest
path. He defines the almost shortest path as the shortest path that goes
from a starting point to a destination point such that no route between
two consecutive points belongs to any shortest path from the starting
point to the destination.

For example, suppose the figure below
represents the map given, with circles representing location points, and
lines representing direct, one-way routes with lengths indicated. The
starting point is marked as S and the destination point is marked as D.
The bold lines belong to a shortest path (in this case there are two
shortest paths, each with total length 4). Thus, the almost shortest
path would be the one indicated by dashed lines (total length 5), as no
route between two consecutive points belongs to any shortest path.
Notice that there could exist more than one possible answer, for
instance if the route with length 3 had length 1. There could exist no
possible answer as well.

Input

The input contains several test cases. The first line of a test case contains two integers N (2 ≤ N ≤ 500) and M (1 ≤ M ≤ 104),
separated by a single space, indicating respectively the number of
points in the map and the number of existing one-way routes connecting
two points directly. Each point is identified by an integer between 0
and N -1. The second line contains two integers S and D, separated by a single space, indicating respectively the starting and the destination points (SD; 0 ≤ S, D < N).

Each one of the following M lines contains three integers U, V and P (UV; 0 ≤ U, V < N; 1 ≤ P ≤ 103), separated by single spaces, indicating the existence of a one-way route from U to V with distance P. There is at most one route from a given point U to a given point V, but notice that the existence of a route from U to V does not imply there is a route from V to U,
and, if such road exists, it can have a different length. The end of
input is indicated by a line containing only two zeros separated by a
single space.

Output

For each test case in the input, your program must print a single line, containing -1 if it is not possible to match the requirements, or an integer representing the length of the almost shortest path found.

Example

Input:
7 9
0 6
0 1 1
0 2 1
0 3 2
0 4 3
1 5 2
2 6 4
3 6 2
4 6 4
5 6 1
4 6
0 2
0 1 1
1 2 1
1 3 1
3 2 1
2 0 3
3 0 2
6 8
0 1
0 1 1
0 2 2
0 3 3
2 5 3
3 4 2
4 1 1
5 1 1
3 0 1
0 0 Output:
5
-1
6 题意是给出一个单向图,然后只要这条路径(S->D)的长度和最短路的长度一致,那么这条路上所有的边都删掉之后,再跑一次从S->D的最短路。
反向建边后跑两次dij,然后枚举所有边将属于最短路的边删掉。
 #include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define pii pair<int,int>
#define mp make_pair
struct Edge{
int u,v,w,next;
bool o;
}e1[],e2[];
int tot1,tot2,first1[],first2[];
void add1(int u,int v,int w){
e1[tot1].u=u;
e1[tot1].v=v;
e1[tot1].o=;
e1[tot1].w=w;
e1[tot1].next=first1[u];
first1[u]=tot1++;
}
void add2(int u,int v,int w){
e2[tot2].u=u;
e2[tot2].v=v;
e2[tot2].o=;
e2[tot2].w=w;
e2[tot2].next=first2[u];
first2[u]=tot2++;
}
int N,M,S,D,i,j,k;
bool vis[];
int d1[],d2[];
int dij(int S,int D,int d[],Edge e[],int first[]){
memset(d,inf,sizeof(int)*);
memset(vis,,sizeof(bool)*);
priority_queue<pii,vector<pii>,greater<pii> > q;
q.push(mp(,S));
d[S]=;
while(!q.empty()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=;
for(int i=first[u];i+;i=e[i].next){
if(e[i].o&&d[e[i].v]>d[u]+e[i].w){
d[e[i].v]=d[u]+e[i].w;
q.push(mp(d[e[i].v],e[i].v));
}
}
}
return d[D]==inf?-:d[D];
}
int main()
{
while(cin>>N>>M&&(N||M)){int u,v,w;
cin>>S>>D;
memset(first1,-,sizeof(first1));
memset(first2,-,sizeof(first2));
tot1=tot2=;
while(M--){
scanf("%d%d%d",&u,&v,&w);
add1(u,v,w);
add2(v,u,w);
}
int minn=dij(S,D,d1,e1,first1);
dij(D,S,d2,e2,first2);
for(i=;i<tot1;++i){
if(e1[i].w+d1[e1[i].u]+d2[e1[i].v]==minn) e1[i].o=;
}
cout<<dij(S,D,d1,e1,first1)<<endl;
}
return ;
}
 

最新文章

  1. CI整合Smarty
  2. SQL Server 2008 R2——VC++ ADO 操作 参数化查询
  3. mongoDB 安装配置
  4. html元素
  5. oracle手动删除数据库
  6. JS基础如何理解对象
  7. golang实现udp接入服务器
  8. Gradle构建Java Web应用:Servlet依赖与Tomcat插件(转)
  9. 线程池ThreadPoolExecutor使用简介(转)
  10. [python]_ELVE_pip2和pip3如何共存
  11. Java基础总结1
  12. go使用rpc
  13. Spring错误小结
  14. Hbase 系统架构(zhuan)
  15. java中动态给sql追加?号
  16. 描述linux系统从开机到登陆界面的启动过程
  17. T-SQL查询两个日期之间的休息日(周六周日)天数
  18. DOM父节点、子节点例子
  19. vue-cli 中的静态资源处理
  20. Spring4源码解析:BeanDefinition架构及实现

热门文章

  1. for…else和while…else
  2. discuz debug下载地址
  3. Shiro安全框架入门篇
  4. android studio 版本修改无效解决方案
  5. shell编程(二)
  6. Jquery15 插件
  7. LabVIEW之Vision基础 (一)之软件
  8. SpringBoot ApplicationRunner/CommandLineRunner
  9. Codeforces - 828E DNA Evolution —— 很多棵树状数组
  10. Shell学习小结 - 深入认识变量