UVA11374_Airport Express

时间:2021-05-05 12:06:50

给一个无向图,有的边是特殊边,最多可以取一条特殊边,求最短路,并且输出路径。

这样考虑,加入所有非特殊边,求出每个点到起点和终点的最短路。
然后加入特殊边的时候,如果取当前这条特殊边,那么答案会是两点预处理路径长度加上该边长。直接保存最小答案即可。

不过注意输出的格式还有一些其他的问题,还有加特殊边的时候要考虑是那一端连接起点终点。。。。

召唤代码君:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define maxn 222000
using namespace std; struct heapnode{
int D,U;
bool operator < (heapnode V) const{
return D>V.D;
}
};
const int inf=~0U>>;
int to[maxn],next[maxn],c[maxn],first[maxn],edge;
int dis1[maxn],dis2[maxn],from1[maxn],from2[maxn];
bool done[maxn];
int n,m,s,t,k,ans,len; void _init()
{
edge=-;
for (int i=; i<=n; i++)
first[i]=-,dis1[i]=inf,dis2[i]=inf,from1[i]=-,from2[i]=-;
} void addedge(int U,int V,int W)
{
edge++;
to[edge]=V,c[edge]=W,next[edge]=first[U],first[U]=edge;
edge++;
to[edge]=U,c[edge]=W,next[edge]=first[V],first[V]=edge;
} void dijkstra(int nd,int dis[],int from[])
{
for (int i=; i<=n; i++) done[i]=false;
priority_queue<heapnode> Q;
Q.push((heapnode){,nd}),dis[nd]=;
while (!Q.empty())
{
heapnode cur=Q.top();
Q.pop();
if (done[cur.U]) continue;
else done[cur.U]=true;
for (int i=first[cur.U]; i!=-; i=next[i])
if (dis[cur.U]+c[i]<dis[to[i]])
dis[to[i]]=dis[cur.U]+c[i],from[to[i]]=cur.U,Q.push((heapnode){dis[to[i]],to[i]});
}
} void _input()
{
int U,V,W;
scanf("%d",&m);
while (m--)
{
scanf("%d%d%d",&U,&V,&W);
addedge(U,V,W);
}
dijkstra(s,dis1,from1);
dijkstra(t,dis2,from2);
} void output(int cur)
{
if (cur==-) return ;
output(from1[cur]);
printf("%d ",cur);
} int main()
{
int U,V,W,UU,VV,T=;
while (scanf("%d%d%d",&n,&s,&t)!=EOF)
{
if (T++) puts("");
_init();
_input();
UU=-,len=dis1[t];
scanf("%d",&m);
while (m--)
{
scanf("%d%d%d",&U,&V,&W);
if (dis1[U]+dis2[V]+W<len)
len=dis1[U]+dis2[V]+W,UU=U,VV=V;
if (dis1[V]+dis2[U]+W<len)
len=dis1[V]+dis2[U]+W,UU=V,VV=U;
}
if (UU==-)
{
output(from1[t]);
printf("%d\nTicket Not Used\n%d\n",t,len);
}
else
{
output(UU);
printf("%d",VV);
for (int k=VV; from2[k]!=-; k=from2[k])
printf(" %d",from2[k]);
printf("\n%d\n%d\n",UU,len);
}
}
return ;
}