UVA 11374 Airport Express(dijkstra算法预处理+路径输出)

题目链接
易错点:
1.格式输出,一开始没注意。
2.注意方案中的边也是双向的,一开始没有考虑到后来想了很久才注意到这个问题。

#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pi=acos(-1.0);
const double eps=1e-8;
const double INF=1e20;
const int inf=0x3f3f3f3f;
const int N=1e3+10;
struct node
{
    int u,w;
    node(int uu,int ww):u(uu),w(ww){}
    bool operator < (const node & a)const
    {
        return w>a.w;
    }
};
struct edge
{
    int v,next,w;
}e[N<<1];
int head[N],cnt;
void add(int u,int v,int w)
{
    e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt;
}
int dis1[N],vis1[N],n,dis2[N],vis2[N];
int pre1[N],pre2[N];
int st[N],en[N],cost[N];
void dijkstra1(int s)
{
    for(int i=1;i<=n;i++) dis1[i]=inf,vis1[i]=0;
    dis1[s]=0;
    priority_queue<node>q;
    q.push(node(s,0));
    while(!q.empty())
    {
        node now=q.top();
        q.pop();
        int u=now.u;
        if(vis1[u]) continue;
        vis1[u]=1;
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].v;
            if(dis1[v]>dis1[u]+e[i].w)
            {
                dis1[v]=dis1[u]+e[i].w;
                pre1[v]=u;
                q.push(node(v,dis1[v]));
            }
        }
    }
}
void dijkstra2(int s)
{
    for(int i=1;i<=n;i++) dis2[i]=inf,vis2[i]=0;
    dis2[s]=0;
    priority_queue<node>q;
    q.push(node(s,0));
    while(!q.empty())
    {
        node now=q.top();
        q.pop();
        int u=now.u;
        if(vis2[u]) continue;
        vis2[u]=1;
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].v;
            if(dis2[v]>dis2[u]+e[i].w)
            {
                dis2[v]=dis2[u]+e[i].w;
                pre2[v]=u;
                q.push(node(v,dis2[v]));
            }
        }
    }
}
void print1(int u)
{
    if(pre1[u]==-1) printf("%d",u);
    else
    {
        print1(pre1[u]);
        printf(" %d",u);
    }
}
void print2(int u)
{
    if(pre2[u]==-1) printf("%d",u);
    else
    {
        printf("%d ",u);
        print2(pre2[u]);
    }
}
int main()
{
    int s,e,flag=0;
    while(~scanf("%d%d%d",&n,&s,&e))
    {
        cnt=0;
        for(int i=1;i<=n;i++) head[i]=0;
        if(flag) printf("\n");
        flag=1;
        int m,k,u,v,w;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        scanf("%d",&k);
        for(int i=1;i<=k;i++)
        {
            scanf("%d%d%d",&st[i],&en[i],&cost[i]);
        }
        dijkstra1(s);//从起点到其他点的最短距离
        dijkstra2(e);//从终点
        int ans=dis1[e],ss=s,ee=e,num=0;
        for(int i=1;i<=k;i++)
        {
            u=st[i];
            v=en[i];
            w=cost[i];
            int val=dis1[u]+dis2[v]+w;
            if(ans>val)
            {
                ans=val;
                ss=u;
                ee=v;
                num=i;
            }
            u=en[i];
            v=st[i];
            w=cost[i];
            val=dis1[u]+dis2[v]+w;
            if(ans>val)
            {
                ans=val;
                ss=u;
                ee=v;
                num=i;
            }
        }
        pre1[s]=-1;
        pre2[e]=-1;
        if(!num)
        {
            print1(e);
            printf("\n");
            printf("Ticket Not Used\n");
            printf("%d\n",ans);
            continue;
        }
        print1(ss);
        printf(" ");
        print2(ee);
        printf("\n");
        printf("%d\n",ss);
        printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(算法竞赛入门经典)