UVA11374_Airport Express

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

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

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

召唤代码君:

#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>>3;
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=-1;
    for (int i=1; i<=n; i++)
        first[i]=-1,dis1[i]=inf,dis2[i]=inf,from1[i]=-1,from2[i]=-1;
}

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=1; i<=n; i++) done[i]=false;
    priority_queue<heapnode> Q;
    Q.push((heapnode){0,nd}),dis[nd]=0;
    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!=-1; 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==-1) return ;
    output(from1[cur]);
    printf("%d ",cur);
}

int main()
{
    int U,V,W,UU,VV,T=0;
    while (scanf("%d%d%d",&n,&s,&t)!=EOF)
    {
        if (T++) puts("");
        _init();
        _input();
        UU=-1,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==-1)
        {
            output(from1[t]);
            printf("%d
Ticket Not Used
%d
",t,len);
        }
        else
        {
            output(UU);
            printf("%d",VV);
            for (int k=VV; from2[k]!=-1; k=from2[k])
                printf(" %d",from2[k]);
            printf("
%d
%d
",UU,len);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lochan/p/3858906.html