pat Clase A 1003 Problema de ruta más corta de fuente única

1. El algoritmo dijkstra está
escrito de forma fija. Se cometió un error de bajo nivel en el medio. N son los datos de límite utilizados en varios lugares. Intente no cambiar el valor de N, como while (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. Algoritmo de 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;
}

Supongo que te gusta

Origin blog.csdn.net/sinat_37517996/article/details/104463800
Recomendado
Clasificación