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;
}

猜你喜欢

转载自blog.csdn.net/Willen_/article/details/84072988