pat 클래스 A 1003 단일 소스 최단 경로 문제

1. dijkstra 알고리즘은
고정 된 방식으로 작성됩니다. 중간에 낮은 수준의 오류가 발생했습니다. N은 여러 위치에서 사용되는 경계 데이터입니다. while (N–)과 같이 N의 값을 변경하지 마십시오. ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ ㅇㅇㅇ

#include <cstdio>
#include <climits>
#include <algorithm>

const int maxc = 500;
const int INF = INT_MAX;

int N, M, C1, C2;
int teams[maxc];
int graph[maxc][maxc]={
    
    };
bool confirmed[maxc]={
    
    }; //C1到该城市的最短距离是否已确定
int distance[maxc]; //从C1到i最短路径长度为distance[i]
int path[maxc]={
    
    }; //从C1到i有path[i]条最短路
int r_team[maxc]={
    
    }; //从C1到i在路径最短条件下,最多能累积r_team[i]个救援队

void init();
//在graph上执行djkstra算法,计算出三个数组的结果
void dijkstra();

int main(){
    
    
    scanf("%d%d%d%d", &N, &M, &C1, &C2);
    for(int i=0; i<N; i++) scanf("%d", &teams[i]);
    while(M--){
    
    
        int c1, c2, dis;
        scanf("%d%d%d", &c1, &c2, &dis);
        graph[c1][c2] = graph[c2][c1] = dis;
    }
    init();
    dijkstra();
    printf("%d %d", path[C2], r_team[C2]);

    return 0;
}

void init(){
    
    
    std::fill(distance, distance+N, INF);
    distance[C1] = 0;
    path[C1] = 1;
    r_team[C1] = teams[C1];
    return;
}

void dijkstra(){
    
    
    for(int k=0; k<N; k++){
    
    
        //循环N次,每次确定一个城市的最短距离,包括C1到C1也要确定一次
        //从distance数组中未确定的城市中找到最小的,该城市即确定了最短距离
        int city=-1, min_d=INF;
        for(int i=0; i<N; i++){
    
    
            if(!confirmed[i] && distance[i]<min_d){
    
    
                city = i;
                min_d = distance[i];
            }
        }
        //若所有未确定的城市距离都是INF,说明未确定的点与起点不连通
        if(city==-1) return;
        //否则到达该城市最短距离已确定
        confirmed[city] = true;
        //以city为中介,考察它能到达的未确定的顶点
        for(int i=0; i<N; i++){
    
    
            if(!confirmed[i] && graph[city][i]!=0){
    
    
                if(distance[city]+graph[city][i]<distance[i]){
    
    
                    //以city为中介,能缩短到i的距离。此为第一标准,不管r_team是否变大都更新其值
                    distance[i] = distance[city] + graph[city][i];
                    r_team[i] = r_team[city] + teams[i];
                    path[i] = path[city];
                }
                else if(distance[city]+graph[city][i]==distance[i]){
    
    
                    //以city为中介,和不以它为中介,到i的距离相等
                    path[i] += path[city];
                    //第二标准生效
                    if(r_team[city]+teams[i]>r_team[i]){
    
    
                        r_team[i] = r_team[city]+teams[i];
                    }
                }
            }
        }
    }
    return;
}

2. Bellman Ford 알고리즘

#include <cstdio>
#include <vector>
#include <set>
#include <climits>
#include <algorithm>

using namespace std;

const int maxv = 500;
const int INF = INT_MAX;

struct edge{
    
    
    int e_end, e_weight;
    edge(int a, int b): e_end(a), e_weight(b) {
    
    }
};

int N, M, S, D;
int v_weight[maxv], d[maxv];
int path_count[maxv]={
    
    };
int team[maxv]={
    
    };
vector<edge> graph[maxv];
set<int> pre[maxv];

void init();
void bellmanFord();

int main(){
    
    
    scanf("%d%d%d%d", &N, &M, &S, &D);
    for(int i=0; i<N; i++) scanf("%d", &v_weight[i]);
    while(M--){
    
    
        int c1, c2, l;
        scanf("%d%d%d", &c1, &c2, &l);
        graph[c1].push_back(edge(c2, l));
        graph[c2].push_back(edge(c1, l));
    }
    init();
    bellmanFord();
    printf("%d %d", path_count[D], team[D]);

    return 0;
}

void init(){
    
    
    fill(d, d+N, INF);
    d[S] = 0;
    path_count[S] = 1;
    team[S] = v_weight[S];
    return;
}

void bellmanFord(){
    
    
    for(int k=0; k<N-1; k++){
    
    
        //最多N-1次循环
        for(int i=0; i<N; i++){
    
    
            //每个顶点i
            if(d[i]==INF) continue; //重要
            int e = graph[i].size();
            for(int j=0; j<e; j++){
    
    
                //每条边i -> v
                int v = graph[i][j].e_end;
                int w = graph[i][j].e_weight;
                if(d[i]+w<d[v]){
    
    
                    //第一标准更优。找到更短路径
                    d[v] = d[i] + w;
                    team[v] = team[i] + v_weight[v];
                    path_count[v] = path_count[i];
                    pre[v].clear();
                    pre[v].insert(i);
                }
                else if(d[i]+w==d[v]){
    
    
                    //第一标准失效。找到长度相同的另一条路
                    //重新统计路径条数
                    pre[v].insert(i);
                    path_count[v] = 0;
                    for(set<int>::iterator it=pre[v].begin(); it!=pre[v].end(); it++){
    
    
                        path_count[v] += path_count[*it];
                    }
                    //第二标准更优
                    if(team[i]+v_weight[v]>team[v]){
    
    
                        team[v] = team[i] + v_weight[v];
                    }
                }
            }
        }
    }
    return;
}

추천

출처blog.csdn.net/sinat_37517996/article/details/104463800