题目描述
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 3
0 1
1 2
2 0
样例输出
1
3
-1
注意:还有一种方法,大整数操作
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAXV = 520;
const int INF = 1000000000;
const int MOD = 100000;
int n, m, G[MAXV][MAXV], father[MAXV];
int d[MAXV];
bool vis[MAXV] = {0};
int mod(int a, int b) {
int num = 1;
while(b--) num = (num * a) % MOD;
return num;
}
void Dijkstra(int s) {
fill(d, d + MAXV, INF);
d[s] = 0;
for(int i = 0; i < n; i++) {
int u = -1, MIN = INF;
for(int j = 0; j < n; j++) {
if(!vis[j] && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0; v < n; v++) {
if(!vis[v] && G[u][v] != INF && d[u] + G[u][v] < d[v])
d[v] = G[u][v] + d[u];
}
}
}
void init() {
for(int i = 0; i < MAXV; i++) father[i] = i;
}
int findFather(int x) {
if(x == father[x]) return x;
else {
int F = findFather(father[x]);
father[x] = F;
return F;
}
}
int main()
{
while(cin >> n >> m) {
int a, b;
init();
fill(G[0], G[0] + MAXV * MAXV, INF);
fill(vis, vis + MAXV, 0);
for(int i = 0; i < m; i++) {
scanf("%d %d", &a, &b);
int Fa = findFather(a);
int Fb = findFather(b);
if(Fa != Fb) father[Fa] = Fb;
else continue;
G[a][b] = mod(2, i);
G[b][a] = G[a][b];
}
Dijkstra(0);
for(int i = 1; i < n; i ++)
printf("%d\n", d[i] == INF ? -1 : d[i] % MOD);
}
return 0;
}
177

被折叠的 条评论
为什么被折叠?



