D - Detour Gym - 101666D 详解

Problem D: Detour
9
D Detour
After last year’s edition of the BAPC, you are still stuck
in Delft. In order to participate again this year, you are
going to Amsterdam by bus. During the journey you look
out of the window and look for traffic signs that point in
the direction of Amsterdam. To your surprise, you notice
that the bus is never taking the roads that are pointed out
by the signs!
You think that the bus company might have chosen a route
such that, at no intersection, the bus goes in the direction that is pointed to by the signs.
Your friends, however, find this very unbelievable, and don’t think this is possible. Can you
figure out whether there exists a bus route that satisfies this requirement? Note that a bus
route never visits the same place twice.
A traffic sign pointing in the direction of the shortest route to Amsterdam is placed at every
intersection. You may assume that the input graph is both simple and connected, and that
there is a unique optimal route to Amsterdam from every intersection
A single line containing two integers:
Input:
A single line containing two integers: n
(2≤n≤105), the number of intersections, and m(1≤m≤106), the number of undirected roads that connect the intersections. The intersections are numbered from 0 to n− 1. Delft is denoted by intersection i= 0 and Amsterdam is denoted by intersection i= 1.
Output:
As output, give one of the following:

A path from Delft to Amsterdam that satisfies the requirements, in case such a path exists. A path is specified by a single line containing an integer k , the length of the path, followed by k integers pi that specify the intersections along the path in the order in which they are crossed, with p0 = 0 and pk − 1 =1. The text “ impossible”, if such a path does not exist.
题意,有n个点,从0号n-1号编号,有m条边,输入m条边两边节点和长度,问是否存在一条路径从0号节点到1号节点但是每个节点都不能到当前节点到1号节点最短路径中的下一条节点,如果存在输出经过的节点个数和经过的节点
思路:用地杰斯特拉算法计算每个节点到一号节点的最短路径,然后从0号节点开始dfs,如果当前节点的最短路径dis[u] = dis[u]+length[u][v).说明当前节点不能到达下一节点,继续遍历直到找到可行节点,然后dfs(可行节点)直到到达1号节点,如果最终无法到达则输出“impossible”否则输出路径
代码:
#include
#include <bits/stdc++.h>
#define N 100010
#define LL long long
#define INF 0x3f3f3f3f3f
using namespace std;
typedef pair<LL,int>pa;
vectoredge[N];
LL dis[N];
int path[N], vis[N], flag = 0;
void dijkstra(int x)
{
memset(dis,0x3f,sizeof(dis));
priority_queue<pa,vector,greater >qu;//用优先队列小顶堆,每次找出路径最短的节点,更新其他节点的最短路径,直到队列为空,则更新结束
qu.push(pa(0,x));//先放入1号节点,最短路径为零
dis[x] = 0;
while(!qu.empty())
{
pa u = qu.top();
qu.pop();
for(int i = 0; i<edge[u.second].size(); i++)
{
int v = edge[u.second][i].second;//v表示能到达的节点编号
LL w = edge[u.second][i].first;//w表示v和w的边长
if(w+u.first<dis[v])//更新操作
{
dis[v] = w+u.first;
qu.push(pa(dis[v],v));
}

    }
}

}
void dfs(int x)//从9号开始深搜是否能到1号
{
if(x==1)//表示到达1号节点
{
flag = 1;
return;
}
for(int i = 0; i<edge[x].size(); i++)
{
int v = edge[x][i].second;
if(dis[x]==dis[v]+edge[x][i].first)//每个节点不能走最短路径中的下一个节点
continue;
if(!vis[v])
{
vis[v] = 1;
path[x] = v;//记录当前节点的下一节点
dfs(v);
}
if(flag)
return;
}
}
int main()
{
int n, m;
scanf("%d%d",&n,&m);
int u, v;
LL w;
for(int i = 0; i<m; i++)
{
scanf("%d%d%lld",&u,&v,&w);
edge[u].push_back(pa(w,v));//用vector数组存储当前节点能够到达的节点,first表示两节点间的距离,second表示,下一节点的编号
edge[v].push_back(pa(w,u));//无向图
}
dijkstra(1);//从一号节点开始,找每个节点到一号节点的最短路径
vis[0] = 1;
memset(path,-1,sizeof(path));
dfs(0);
if(flag)
{
vectorans;
int x = 0;
while(x!=-1)
{
ans.push_back(x);//记录路径
x = path[x];
}
printf("%d",ans.size());
for(int i = 0; i<ans.size(); i++)
{
printf(" %d",ans[i]);
}
printf("\n");
}
else
printf(“impossible”);
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值