1.ダイクストラアルゴリズムは
固定された方法で記述されています。途中で低レベルのエラーが発生しました。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.ベルマンフォードアルゴリズム
#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;
}