1. 程式人生 > >Uva 11374 最短路 好題

Uva 11374 最短路 好題

題目連結:點我

題目大意:有n個點,求從s到e的最短路,有m條無向路可以隨意走,k條無向路最多可以走一次也可以不走;

真是不知道方法死也過不去了,知道了秒過,鍛鍊思維。

程式碼很醜見諒。

思路:求s到各個點的最短路,再求e到各點的最短路,然後列舉k條路,求出最短路然後列印路徑

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define text cout<<"text"<<endl;
using namespace std;
typedef long long LL;
struct node{
    int y,l,next;
}k[20100];
int head[510];
char rode[510];
int dis1[510],vis1[510],pre1[510];
void spfa1(int l){
    for(int i=0;i<=500;i++){
        dis1[i]=2000000;
        vis1[i]=0;
        pre1[i]=-1;
    }
    dis1[l]=0;
    vis1[l]=1;
    queue<int>qu;
    qu.push(l);
    while(!qu.empty()){
        int x=qu.front();
        qu.pop();
        vis1[x]=0;
        for(int i=head[x];i!=-1;i=k[i].next){
            int y=k[i].y;
            if(dis1[y]>dis1[x]+k[i].l){
                dis1[y]=dis1[x]+k[i].l;
                pre1[y]=x;
                if(!vis1[y]){
                    vis1[y]=1;
                    qu.push(y);
                }
            }
        }
    }
}
int dis2[510],vis2[510],pre2[510];
void spfa2(int l){
    for(int i=0;i<=500;i++){
        dis2[i]=2000000;
        vis2[i]=0;
        pre2[i]=-1;
    }
    dis2[l]=0;
    vis2[l]=1;
    queue<int>qu;
    qu.push(l);
    while(!qu.empty()){
        int x=qu.front();
        qu.pop();
        vis2[x]=0;
        for(int i=head[x];i!=-1;i=k[i].next){
            int y=k[i].y;
            if(dis2[y]>dis2[x]+k[i].l){
                dis2[y]=dis2[x]+k[i].l;
                pre2[y]=x;
                if(!vis2[y]){
                    vis2[y]=1;
                    qu.push(y);
                }
            }
        }
    }
}
int main(){
    int S,E,N,M,K,flog=0;
    while(cin>>N>>S>>E){
        if(flog)printf("\n");
        else flog=1;
        int x,y,z,h=0;
        memset(head,-1,sizeof(head));
        scanf("%d",&M);
        while(M--){
            scanf("%d%d%d",&x,&y,&z);
            k[h].y=y;
            k[h].l=z;
            k[h].next=head[x];
            head[x]=h++;
            k[h].y=x;
            k[h].l=z;
            k[h].next=head[y];
            head[y]=h++;
        }
        spfa1(S);
        spfa2(E);
        int time=dis1[E];
        int change1=-1,change2=-1;
        scanf("%d",&K);
        for(int i=0;i<K;i++){
            scanf("%d%d%d",&x,&y,&z);
            int t1=dis1[x]+dis2[y]+z;
            if(t1<time){
                time=t1;
                change1=x;
                change2=y;
            }
            int t2=dis1[y]+dis2[x]+z;
            if(t2<time){
                time=t2;
                change1=y;
                change2=x;
            }
        }
        if(change1==-1){
            int ch[1100];
            int i=E,len=0;
            memset(ch,0,sizeof(ch));
            while(1){
                ch[len++]=i;
                i=pre1[i];
                if(i==-1)break;
            }
            for(int i=len-1;i>=0;i--){
                printf("%d",ch[i]);
                if(i)printf(" ");
            }
            printf("\nTicket Not Used\n");
        }
        else {
            int ch[1100];
            int i=change1,len=0;
            memset(ch,0,sizeof(ch));
            while(1){
                ch[len++]=i;
                i=pre1[i];
                if(i==-1)break;
            }
            for(int i=len-1;i>=0;i--){
                printf("%d",ch[i]);
                if(i)printf(" ");
            }

            memset(ch,0,sizeof(ch));
            i=change2;
            while(1){
                printf(" %d",i);
                i=pre2[i];
                if(i==-1)break;
            }
            printf("\n%d\n",change1);
        }
        cout<<time<<endl;
    }
    return 0;
}