1. 程式人生 > >1003 Emergency (25 point(s))

1003 Emergency (25 point(s))

 1003 Emergency (25 point(s))

SPFA 部分未通過  19分

思路:

1.SPFA可以在有路徑長度為負的情況下,也能夠實現最短路徑

2.需要一個距離陣列  d  對應的表示該源到圖中所有點的最短距離 初始設為INF

3.需要一個是否在佇列的判定陣列

4.需要一個每個節點入隊次數的陣列,因為可能有負環,所以要做好控制,另外,因為最短路徑其實是可以生成最短路徑樹的,最短路徑樹的長度最大不超過定點個樹V,並且在起始的時候d[start] =0 ,就是從開始點的起始位置,實際上,距離就是0,所以已經定好了,基於這樣的理論,所以每個節點實際上入隊不會超過v次,也即整個最短路徑樹的更新次數.

5.若對應的點的距離改變了,那麼相應的後續與相連的資料必定也要在最短路徑上發生變更,這就是實現思想.

#include<vector>
#include<iostream>
#include<queue>
#include<set>
using namespace std;

struct node{
    int v;
    int l;
    node(int v,int l):v(v),l(l){}
};

int main(){
    int const INF = 0x3f3f3f3f;
    int const MAXN = 510;

    //map
    vector<node>map[MAXN];
    //if in queue;
    bool in_que[MAXN];
    fill(in_que,in_que+MAXN,false);

    //in queue number
    int in_count[MAXN];
    fill(in_count,in_count+MAXN,0);

    //wegiht count;
    int w[MAXN];
    fill(w,w+MAXN,0);

    //wegiht ;
    int weight[MAXN];

    //distence;
    int d[MAXN];
    fill(d,d+MAXN,INF);

    int num[MAXN];
    fill(num,num+MAXN,0);


    queue<int> que_map;

    set<int> pre[MAXN];

    int N,M,C1,C2;

    cin>>N>>M>>C1>>C2;

    for(int i=0;i<N;i++){
        cin>>weight[i];
    }

    for(int i=0;i<M;i++){
        int c1,c2,lenth;
        cin>>c1>>c2>>lenth;
        map[c1].push_back(node(c2,lenth));
        map[c2].push_back(node(c1,lenth));

    }

//    for(int i=0;i<N;i++){

//        int length = map[i].size();
//        for(int j=0;j<length;j++){
//            cout<<i<<" "<<map[i][j].v<<" "<<map[i][j].l<<endl;
//        }
//    }

    d[C1] = 0;
    que_map.push(C1);
    w[C1] = weight[C1];
    in_que[C1] = true;
    in_count[C1] = 1;
    num[C1] = 1;

    while(!que_map.empty()){

        int u = que_map.front();

        que_map.pop();
        in_que[u] = false;

        if(in_count[u]>=N){
            break;
        }

        int lenth = map[u].size();

        for(int i=0;i<lenth;i++){
            int v = map[u][i].v;
            int l = map[u][i].l;

            if(d[u]+l<d[v]){
                d[v] = d[u]+l;
                w[v] = w[u]+weight[v];
                num[v]=num[u];
                pre[v].clear();
                pre[v].insert(u);
                if(!in_que[v]){
                    que_map.push(v);
                    in_que[v] = true;
                    in_count[v]++;
                }
            }else if(d[u]+l==d[v]){
                pre[v].insert(u);
                num[v] = 0;
                set<int>::iterator it = pre[v].begin();
                for(;it!=pre[v].end();it++){
                    num[v]+=num[*it];
                }
                if(w[u]+weight[v]>w[v]){
                     w[v] = w[u]+weight[v];
                }
            }
        }
    }
    cout<<num[C2]<<" "<<w[C2]<<endl;

    return 0;
}