PAT 甲级 A1003 (2019/02/24)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXV = 510;       //  最大顶点数 
const int INF = 1000000000;     //  无穷大 
//顶点数,边数,起点,终点,邻接矩阵,点权 
int V, E, start, end, G[MAXV][MAXV], weight[MAXV];
//最短距离,最大点权和,最短路径条数 
int dist[MAXV], w[MAXV], num[MAXV];
//顶点i是否被访问 
bool visit[MAXV] = {false};

void Dijkstra(int s){   //  s为起点 
    fill(dist, dist + MAXV, INF);
    memset(num, 0, sizeof(num));
    memset(w, 0, sizeof(w));
    dist[s] = 0;
    w[s] = weight[s];
    num[s] = 1;
    for(int i = 0; i < V; i++){ //  循环V次 
        int u = -1, MIN = INF;  //  u使dist[u]最小,MIN存放最小的d[u] 
        for(int j = 0; j < V; j++){ //  找到未访问的顶点d[]最小 
            if(visit[j] == false && dist[j] < MIN){
                u = j;
                MIN = dist[j];
            }
        }
        //  找不到小于INF的d[u],说明剩下的顶点和s不连通
        if(u == -1) return;      
        visit[u] = true;    //  标记u已被访问 
        for(int v = 0; v < V; v++){
            // 如果v未被访问,且u能到达v,且以u为中介的点更优 
            if(visit[v] == false && G[u][v] != INF){
                if(dist[u] + G[u][v] < dist[v]){    //  以u为中介点时能令d[v]更小 
                    dist[v] = dist[u] + G[u][v];    //  覆盖d[v] 
                    w[v] = w[u] + weight[v];    //  覆盖w[v] 
                    num[v] = num[u];    //  覆盖num[v] 
                }else if(dist[u] + G[u][v] == dist[v]){ //  找到一条相同长度的路径 
                    if(w[u] + weight[v] > w[v]){    //  以u为中介点时点权之和更大 
                        w[v] = w[u] + weight[v];    //  w[v]继承自w[u] 
                    }
                    //  注意最短路径条数与点权无关,必须写在外面
                    num[v] += num[u]; 
                }
            }
        }
    } 
}

int main(){
    scanf("%d %d %d %d", &V, &E, &start, &end);
    for(int i = 0; i < V; i++){     //  读入点权 
        scanf("%d", &weight[i]);
    }
    int a, b;
    fill(G[0], G[0] + MAXV * MAXV, INF);    //  初始化图 
    for(int i = 0; i < E; i++){
        scanf("%d %d", &a, &b);
        scanf("%d", &G[a][b]);  //  读入边权 
        G[b][a] = G[a][b];
    }
    Dijkstra(start);    //  Dijkstra算法入口 
    printf("%d %d", num[end], w[end]);  //  最短距离条数,最短路径中的最大点权 
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zjsaipplp/p/10427564.html
今日推荐