-
题目描述:
-
N个城市,标号从0到N-1,M条道路,第K条道路(K从0开始)的长度为2^K,求编号为0的城市到其他城市的最短距离
-
输入:
-
第一行两个正整数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> struct bigInt { int digit[100]; int size; }G[100][100]; //邻接矩阵 void init(bigInt &a) //初始化高精度整数 { for(int i = 0; i < 100; i++) a.digit[i] = 0; a.size = 0; } void max_init(bigInt &a) //若两城市间没路,初始化为最大值 { for(int i = 0; i < 50; i++) a.digit[i] = 9999; a.size = 50; } bool Isbig(bigInt a, bigInt b) //比较高精度整数大小 { if(a.size > b.size) return true; else if(a.size < b.size) return false; else { for(int i = a.size - 1; i >= 0; i--) { if(a.digit[i] > b.digit[i]) return true; else if(a.digit[i] < b.digit[i]) return false; } return true; } } bool Isinit(bigInt a) //dist数组元素是否为初始值-1 { if(a.size == 1 && a.digit[a.size-1] == -1) return true; else return false; } bigInt add(bigInt a, bigInt b) //高精度整数相加 { bigInt ret; init(ret); int bound = a.size > b.size ? a.size : b.size; int carry = 0; for(int i = 0; i < bound; i++) { int tmp = a.digit[i] + b.digit[i] + carry; carry = tmp / 10000; ret.digit[ret.size++] = tmp % 10000; } if(carry != 0) ret.digit[ret.size++] = carry; return ret; } bigInt dist[101]; bool mark[101]; int main() { //freopen("1100in.txt","r",stdin); int N, M; while(scanf("%d%d",&N,&M) != EOF) { int i, j; for(i = 0; i < N; i++) //初始化dist和mark数组 { dist[i].digit[0] = -1; dist[i].size = 1; mark[i] = false; } for(i = 0; i < N; i++) // 初始化邻接矩阵 { for(j = 0; j < N; j++) { max_init(G[i][j]); } } bigInt mid; init(mid); mid.digit[0] = 1; mid.size = 1; for(i = 0; i < M; i++) { int a, b; scanf("%d%d",&a,&b); G[a][b] = mid; G[b][a] = mid; mid = add(mid,mid); /*for(j = mid.size-1; j >= 0; j--) printf("%d",mid.digit[j]); printf("\n");*/ } dist[0].digit[0] = 0; // dijkstra之 dist[0].size = 1; mark[0] = true; int newP = 0; for(i = 1; i < N; i++) { for(j = 0; j < N; j++) { if(mark[j] == true) continue; if(G[newP][j].size == 50) //若newP与j之间没有路,则跳过 continue; if(Isinit(dist[j]) || Isbig(dist[j],add(G[newP][j],dist[newP]))) dist[j] = add(G[newP][j],dist[newP]); } bigInt min; max_init(min); for(j = 0; j < N; j++) { if(Isinit(dist[j]) || mark[j] == true) continue; if(Isbig(min,dist[j])) { min = dist[j]; newP = j; } } mark[newP] = true; } for(i = 1; i < N; i++) //输出,过大则mod100000 { if(Isinit(dist[i])) printf("-1\n"); else { if(dist[i].size == 1) printf("%d\n",dist[i].digit[0]); else { if(dist[i].digit[1]%10 != 0) { printf("%d",dist[i].digit[1]%10); printf("%04d\n",dist[i].digit[0]); } else printf("%d\n",dist[i].digit[0]); } } } } return 0; }