第一行两个正整数N(2<=N<=100)M(M<=500),表示有N个城市,M条道路 接下来M行两个整数,表示相连的两个城市的编号
N-1行,表示0号城市到其他城市的最短路,如果无法到达,输出-1,数值太大的以MOD 100000 的结果输出。
4 4 1 2 2 3 1 3 0 1
8 9 11
#include <stdio.h>
#include <stdlib.h>
#define mod 100000
// 输入一条新路a<=>b后,会存在三层连接的发生:
// 1.两个根结点a, b之间的连接
// 2.两个根节点与另一方的下属结点之间的连接
// 3.下属结点之间的连接
void init_dist(int N, int dist[N][N]){
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
dist[i][j] = i==j ? 0 : -1;
}
}
}
void link_node(int N, int from, int to, int dist[N][N], int now_dis){
dist[from][to] = now_dis;
dist[to][from] = now_dis;
}
void renew_dist(int N, int from, int to, int dist[N][N], int now_dis){
// 第一步
link_node(N, from, to, dist, now_dis);
// 第二步
int waitlist[2][N], length0=0, length1=0;
for(int i=0; i<N; i++){
if(from !=i && dist[from][i] != -1){ //i是from下属结点,让to和i连接,并让i入(from队)
link_node(N, i, to, dist, (dist[from][i] + now_dis) % mod);
waitlist[0][length0] = i;
length0++;
}else if(to!=i && dist[to][i] != -1){ //i是to的下属结点,让from和i连接,并让i入(to队)
link_node(N, i, from, dist, (dist[to][i] + now_dis) % mod);
waitlist[1][length1] = i;
length1++;
}
}
// 第三步
int a, b; //美观起见
for(int i=0; i<length0; i++){
a = waitlist[0][i];
for(int j=0; j<length1; j++){
b = waitlist[1][j];
link_node(N, a, b, dist, (dist[a][from] + dist[from][b]) % mod);
}
}
}
int main() {
int N, M;
int from, to;
while (scanf("%d %d", &N, &M) != EOF) {
int now_dis = 1;
int dist[N][N];
init_dist(N, dist);
for(int i=0; i<M; i++){
scanf("%d %d", &from, &to);
if(dist[from][to] == -1){
renew_dist(N, from, to, dist, now_dis);
}
now_dis = (now_dis*2) % mod;
}
for(int i=1; i<N; i++){
printf("%d\n", dist[0][i]);
}
}
return 0;
}