Ideal Path UVA - 1599

題目鏈接

這道題利用兩次BFS來求解:

  1. 由於題目有兩個限制條件:最短路徑,字典序顏色,假設我們從後往前BFS,將得到每個節點到終點的步數,這樣就知道起點到終點的步數,同時中間的路徑也可以由每次遞減來確定,第二次BFS中維護最小字典序即完成。
  2. 輸入涉及到重複和自環,要避免重複和過濾自環。
  3. 由於數量級很大采用鄰接表存儲數據。

C++代碼描述

#include<bits/stdc++.h> 
using namespace std;
const int maxn=100000;
const int inf=0x7fffffff;
int d[maxn],res[maxn];
bool vist[maxn],inqueue[maxn];
int n,m,v;

struct Node{
    int link,color;
    Node(int l,int c):link(l),color(c){}
};//節點定義
vector<Node> linklist[maxn];//鄰接表定義 
void dfs(int start,int end){
    memset(inqueue,0,sizeof(inqueue));
    memset(vist,0,sizeof(vist));
    queue<int>  q;
    q.push(start);
    if(start){
        while(!q.empty()){
            int u=q.front();q.pop();vist[u]=1;
            for(int i=0;i<linklist[u].size();i++)
                if(!vist[v=linklist[u][i].link]&&!inqueue[v]){
                    d[v]=d[u]+1;
                    if(v==0)    return;
                    q.push(v);
                    inqueue[v]=1;
                }
        }
    }else{
        memset(res,0,sizeof(int)*n);
        while(!q.empty()){
            int u=q.front();q.pop();vist[u]=1;
            if(u==n-1)  return;
            int minc=inf;
            for(int i=0;i<linklist[u].size();i++)if(!vist[v=linklist[u][i].link]&&d[v]==d[u]-1)minc=min(minc,linklist[u][i].color);
            for(int i=0;i<linklist[u].size();i++)if(!vist[v=linklist[u][i].link]&&d[v]==d[u]-1&&!inqueue[v]&&linklist[u][i].color==minc)inqueue[v]=1,q.push(v);
            int index=d[0]-d[u];
            if(res[index]==0)   res[index]=minc;
            else    res[index]=min(res[index],minc);
        }
    }
}
int main(){
//  freopen("F://inp.txt","r",stdin);
    while(cin>>n>>m){
        for(int i=0;i<n;i++)    linklist[i].clear();
        memset(d,-1,sizeof(d));d[n-1]=0;
        while(m--){
            int a,b,c;
            cin>>a>>b>>c;
            if(a!=b){
                linklist[a-1].push_back(Node(b-1,c));
                linklist[b-1].push_back(Node(a-1,c));
            }
        }
        dfs(n-1,0);
        dfs(0,n-1);
        cout<<d[0]<<endl<<res[0];
        for(int i=1;i<d[0];i++) cout<<" "<<res[i];
        cout<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章