UVA1599 Ideal Path

UVA1599 Ideal Path

問題描述

給定一個無向聯通圖G,G中有N個頂點,M條邊,每條邊的長度爲一個單位,並有一個整數表示這條邊的顏色,求從1到N的最短路,如果有多個,則找出顏色字典序最小的路徑。

思路:

從N開始進行一次BFS,對於一個節點y,記錄y節點的距離dis[y]和對應到達y的邊e=pre[y],由此,根據pre[y]可以回溯出N到y的路徑。當某個節點y被再次訪問時,並且新的距離和舊的距離相等(事實上,不存在第二次訪問y時,距離更小或者更大的情況),表示N到y有了一條新的路徑,此時藉助之前保存的pre[j]信息和新的路徑對比,保留字典序小的路徑。

代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

typedef struct edge{
    int x,y,c;
    int nxt;
}edge;
edge buf[400000+20];
int head[100000+20];
int pre[100000+20];
int que[100000+20];
int dis[100000+20];
char vis[100000+20];
int cnt,top,tail;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m;
    int i,j,k,x,y,c;
    int st,ed;
    while(cin>>n>>m){
        cnt=1; st=1; ed=n; top=0;tail=0;
        memset(head,0,sizeof(head));
        memset(pre,0,sizeof(pre));
        memset(dis,0,sizeof(dis));
        memset(vis,0,sizeof(vis));
        for(i=1,j=0;j<m;j++,i+=2){
            cin>>x>>y>>c;
            buf[i].x=x; buf[i].y=y; buf[i].c=c;
            buf[i+1].x=y; buf[i+1].y=x; buf[i+1].c=c;

            buf[i].nxt=head[x]; head[x]=i;
            buf[i+1].nxt=head[y]; head[y]=i+1;
        }
        que[0]=ed; tail=1; pre[1]=pre[0]=0;
        dis[ed]=0; vis[ed]=1;
        while(top<tail){
            x=que[top++];
            for(j=head[x];j;j=buf[j].nxt){
                y=buf[j].y; c=buf[j].c;
                if(vis[y]){
                    if(dis[y]==dis[x]+1){ ///距離相等
                        //xx=x; yy=y;
                        int e1=pre[y],e2=j;
                        while(e1!=e2 && buf[e1].c==buf[e2].c){ ///兩條路徑一定會同時結束
                            e1=pre[buf[e1].x]; e2=pre[buf[e2].x];
                        }
                        if(buf[e1].c>buf[e2].c){
                            pre[y]=j;
                        }
                    }
                }else{
                    vis[y]=1;
                    pre[y]=j;
                    dis[y]=dis[x]+1;
                    que[tail++]=y;
                }
            }
        }
        cout<<dis[st]<<endl;
        for(int e=pre[st],i=0;i<dis[st];i++){
            if(i) cout<<' ';
            cout<<buf[e].c;
            e=pre[buf[e].x];
        }
        cout<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章