版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xp1994816/article/details/52463544
学习了。Dijkstra+高精度整数。
<pre class="cpp" name="code">#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
#define MAX 101
struct bigInteger{
int digit[MAX];
int size;
void init(){
for(int i = 0 ; i < MAX ; ++i){
digit[i] = 0;
}
size = 0;
}
void set(char s[]){ //用一个小整数来设置高精度整数
init();
int l = strlen(s);
for(int i = l-1 , j = 0 , t = 0 , c = 1 ; i >= 0 ; --i){
t += (s[i]-'0') * c;
j++;
c *= 10;
if(j == 4 || i == 0){
digit[size++] = t;
j = 0; t = 0; c = 1;
}
}
}
bigInteger operator * (const int x) const {
bigInteger ret;
ret.init();
int carry = 0;
for(int i = 0 ; i < size ; ++i){
int t = (digit[i] * x + carry) % 10000;
carry = (digit[i] * x + carry) / 10000;
ret.digit[ret.size++] = t;
}
if(carry != 0){
ret.digit[ret.size++] = carry;
}
return ret;
}
bigInteger operator + (const bigInteger &A) const{
bigInteger ret;
ret.init();
int carry = 0;
for(int i = 0 ; i < size || i < A.size ; ++i){
int t = digit[i] + A.digit[i] + carry;
carry = t / 10000;
t = t % 10000;
ret.digit[ret.size++] = t;
}
if(carry != 0){
ret.digit[ret.size++] = carry;
}
return ret;
}
bool operator < (const bigInteger &A) const {
if(size != A.size){
return size<A.size;
}
else{
for(int i = size - 1 ; i >= 0 ; --i){
if(digit[i] != A.digit[i]){
return digit[i] < A.digit[i];
}
}
}
}
int operator % (const int x) const {
int r = 0;
for(int i = size - 1 ; i >= 0 ; --i){
int t = r*10000 + digit[i];
r = t % x;
}
return r;
}
};
struct E{
int nextNode;
bigInteger c;
};
vector<E> edge[1001];
bool mark[1001];
bigInteger dis[1001];
bool flag[1001]; //false为不可达
int main()
{
int n , m;
while(scanf("%d%d",&n,&m) != EOF){
for(int i = 0 ; i < n ; ++i){
edge[i].clear();
}
for(int i = 0 ; i < n ; ++i){
dis[i].init();
mark[i] = false;
flag[i] = false;
}
bigInteger w ;
w.set("1");
for(int i = 0 ; i < m ; ++i){
int a , b;
scanf("%d%d",&a,&b);
E tmp;
tmp.c = w;
w = w * 2;
tmp.nextNode = b;
edge[a].push_back(tmp);
tmp.nextNode = a;
edge[b].push_back(tmp);
}
dis[0].set("0");
mark[0] = true;
flag[0] = true;
int newp = 0;
for(int i = 1 ; i < n ; ++i){ //循环n-1次,按顺序确定其它n-1个点的最短路径长度最短路径递增的
for(int j = 0 ; j < edge[newp].size() ; ++j){
int t = edge[newp][j].nextNode;
bigInteger t_c = edge[newp][j].c;
if(mark[t] == true) continue;
if(flag[t] == false || dis[newp] + t_c < dis[t]){
dis[t] = dis[newp] + t_c;
flag[t] = true;
}
}
bigInteger min;
min.set("9999999999999999999999999999999999999999999");
for(int j = 0 ; j <= n ; j++){
if(mark[j] == true) continue;
if(flag[j] == false) continue;
if(dis[j] < min){
min = dis[j];
newp = j;
}
}
mark[newp] = true;
}
for(int i = 1 ; i < n ; ++i){
if(flag[i] == false){
printf("-1\n");
}
else{
printf("%d\n",dis[i]%100000);
}
}
}
return 0;
}