问题 C: 最短路径
时间限制: 1 Sec 内存限制: 32 MB
献花: 101 解决: 17
[献花][花圈][TK题库]
题目描述
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
此题不能简单的数据类型然后直接套最短路径算法,2^500太大,无法正常保存,要么使用大整数运算,或者使用并查集结合快速幂求解
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <cfloat>
#include <map>
#define INF -1
using namespace std;
const int MaxN = 102;
int G[MaxN][MaxN];
int root[MaxN];
int N;
int Qpow(int x, int y, int mod)
{
int res = 1;
long long a = x, b = y;
while (b > 0)
{
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void Init(int n)
{
for (int i = 0; i < n; ++i)
{
root[i] = i;
G[i][i] = 0;
}
}
int findroot(int a)
{
while (a != root[a])
a = root[a];
return a;
}
int main()
{
#ifdef _DEBUG
freopen("data.txt", "r+", stdin);
#endif // _DEBUG
std::ios::sync_with_stdio(false);
int M;
while(cin >> N >> M)
{
fill(G[0], G[0] + (N + 1) * MaxN, INF);
Init(N);
for (int k = 0; k < M; ++k)
{
int u, v, uroot, vroot,d;
cin >> u >> v;
uroot = findroot(u);
vroot = findroot(v);
if (uroot != vroot)
{
d = Qpow(2, k, 100000);
for (int i = 0; i < N; ++i)
{
if (uroot == findroot(i))
{
for(int j = 0;j<N;++j)
{
if (vroot == findroot(j))
{
G[i][j] = G[j][i] = (d + G[i][u] + G[v][j]) % 100000;
}
}
}
}
root[vroot] = uroot;
}
}
int root = findroot(0);
for (int i = 1; i < N; ++i)
{
if (root != findroot(i))
cout << -1 << endl;
else
cout << G[0][i] << endl;
}
}
return 0;
}
/**************************************************************
Problem: 1956
User: Sharwen
Language: C++
Result: 升仙
Time:6 ms
Memory:1736 kb
****************************************************************/