题目描述:
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
来源:
2010年上海交通大学计算机研究生机试真题
#include <cstdio>
#include <vector>
#define N 102
using namespace std;
struct bigInteger{
int digit[1000];
int size;
void init(){
size = 0;
for(int i = 0;i < 1000;i++)
digit[i] = 0;
}
void set(int x){
init();
while(x != 0){
digit[size++] = x % 10000;
x /= 10000;
}
}
// +
bigInteger operator + (const bigInteger& c)const{
bigInteger res;
res.init();
int carry = 0;
for(int i = 0;i < size || i < c.size;i++){
carry = digit[i] + c.digit[i] + carry;
res.digit[res.size++] = carry % 10000;
carry /= 10000;
}
if(carry != 0){
res.digit[res.size++] = carry;
}
return res;
}
// *
bigInteger operator * (const int& c)const{
bigInteger res;
res.init();
int carry = 0;
for(int i = 0;i < size;i++){
carry = digit[i] * c + carry;
res.digit[res.size++] = carry %10000;
carry /= 10000;
}
while(carry != 0){
res.digit[res.size++] = carry % 10000;
carry /= 10000;
}
return res;
}
// <
bool operator < (const bigInteger& a)const{
if(size != a.size)return size < a.size;
for(int i = size - 1;i >= 0;i--){
if(digit[i] != a.digit[i])
return digit[i] < a.digit[i];
}
}
// ==
/*
bool operator == (bigInteger a){
return !(*this < a || a < *this);
}
*/
//Inf
void Inf(){
size = 1000;
for(int i = 0;i < 1000;i++)
digit[i] = 9999;
}
bool equal(){
if(size == 1 && digit[0] == -1)return true;
else return false;
}
void set(){
size = 1;
digit[0] = -1;
}
void print(){
for(int i = size -1;i >= 0;i--)
printf("%d",digit[i]);
printf("\n");
}
void print2(){
if(digit[1]%10 != 0)
{
printf("%d",digit[1]%10);
printf("%04d\n",digit[0]);
}
else
printf("%d\n",digit[0]);
}
int operator%(const int& x)const{
int r=0;
for(int i=size-1;i>=0;i--)
{
r=((r*10000)+digit[i])%x;
}
return r;
}
};
struct edge{
int t;
bigInteger cost;
};
int main()
{
bigInteger dist[N];
vector<edge> graph[N];
bool mark[N];
int n,m;
while(scanf("%d%d",&n,&m) != EOF){
if(n == 0 && m == 0)break;
for(int i=0;i<n;i++)
graph[i].clear();
bigInteger buf;
bool first = true;
for(int i = 1;i <= m;i++){
int from,to;
scanf("%d%d",&from,&to);
edge tmp;
//cost : i^k 二分法求得
if(first){
buf.set(1);
first = false;
}
else buf = buf * 2;
tmp.cost = buf;
tmp.t = to;
graph[from].push_back(tmp);
tmp.t = from;
graph[to].push_back(tmp);
}
/*验证输入是否正确
for(int i = 0;i <= n;i++){
for(int j = 0;j < graph[i].size();j++){
graph[i][j].cost.print();
}
}*/
for(int i = 0;i < n;i++){
dist[i].set();
mark[i] = false;
}
dist[0].set(0);
mark[0] = true;
int newP = 0;
for(int i = 0;i < n-1;i++){
for(unsigned int j = 0;j < graph[newP].size();j++){
int to = graph[newP][j].t;
bigInteger c = graph[newP][j].cost;
if(dist[to].equal()|| dist[newP] + c < dist[to]){
dist[to] = dist[newP] + c;
}
}
bigInteger min;
min.Inf();
for(int j = 0;j <= n-1;j++){
if(dist[j].equal())continue;
if(mark[j] == true)continue;
if(dist[j] < min){
newP = j;
min = dist[j];
}
}
mark[newP] = true;
}
for(int i = 1;i <= n-1;i++){
if(dist[i].equal())printf("-1\n");
else{
printf("%d\n",dist[i] % 100000);
}
}
}
return 0;
}