九度OJ1100最短路径(高精度)

题目描述:

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
ac代码如下:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<string.h>

using namespace std;
#define MAXSIZE 101
struct bigdata{
	int buf[100];
	int size;
	void init(){
		for(int i=0;i<100;i++)
			buf[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)
			{
				buf[size++]=t;
				j=0;
				t=0;
				c=1;
			}
		}
	}
	bigdata operator+(const bigdata& B)const{
		bigdata res;
		res.init();
		int carry=0;
		for(int i=0;i<size||i<B.size;i++)
		{
			int tmp=buf[i]+B.buf[i]+carry;
			res.buf[res.size++]=tmp%10000;
			carry=tmp/10000;
		}
		if(carry!=0)
			res.buf[res.size++]=carry;
		return res;
	}
	bigdata operator*(const int& x)const{
		bigdata res;
		res.init();
		int carry=0;
		for(int i=0;i<size;i++)
		{
			int tmp=buf[i]*x+carry;
			res.buf[res.size++]=tmp%10000;
			carry=tmp/10000;
		}
		if(carry!=0)
			res.buf[res.size++]=carry;
		return res;
	}
	bool operator<(const bigdata& B)const{
		if(size!=B.size)
			return size<B.size;
		else
			for(int i=size-1;i>=0;i--)
			{
				if(buf[i]!=B.buf[i])
					return buf[i]<B.buf[i];
			}
	}
	int operator%(const int& x)const{
		int r=0;
		for(int i=size-1;i>=0;i--)
		{
			r=((r*10000)+buf[i])%x;
		}
		return r;
	}
};





struct Edge{
	int next;//代表直接相邻的顶点
	bigdata d;
};
vector<Edge> edge[1001];
bool mark[1001];
bigdata dis[1001];
bool flag[1001];//false为不可达
int main(){
	int n,m;
	while(cin>>n>>m&&n!=0&&m!=0)
	{
		for(int i=0;i<n;i++)
			edge[i].clear();
		bigdata dd;
		dd.set("1");
		for(int i=0;i<m;i++){
			int a,b;
			cin>>a>>b;
			Edge tmp;
			tmp.d=dd;
			dd=dd*2;
			tmp.next=b;
			edge[a].push_back(tmp);
			tmp.next=a;
			edge[b].push_back(tmp);
		}
		for(int i=0;i<n;i++)
		{
			dis[i].init();
			mark[i]=false;
			flag[i]=false;
		}
		dis[0].set("0");
		mark[0]=true;
		flag[0]=true;
		int newP=0;
		for(int i=1;i<n;i++)
		{
			for(int j=0;j<edge[newP].size();j++)
			{
				int t=edge[newP][j].next;
				bigdata distance=edge[newP][j].d;
				if(mark[t]==true) continue;
				if(flag[t]==false||dis[newP]+distance<dis[t])
				{
					dis[t]=dis[newP]+distance;
					flag[t]=true;
				}
			}
			bigdata min;
			min.set("999999999999999999999999999999999999999999999999999999999999999");
		
			for(int j=1;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)
				cout<<"-1"<<endl;
			else
				cout<<dis[i]%100000<<endl;
		}
	}
	return 0;
}



 
 
 
 
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值