最短路径
2017-02-22 20:08
162 查看
最短路径
题目来源:最短路径
思路分析
由于是单源最短路径问题,所以采用Dijkstra算法由于题目中距离很大,超出整数表示范围,所以自定义bigInteger,用于保存高精度整数。
代码
#include <stdio.h> #include <vector> using namespace std; struct bigInteger{ //定义高精度整数,用于保存距离 int digit[1001]; int size; void init(){ for(int i=0; i<1001; i++){ digit[i] = 0; } size = 0; } void set(int x){ init(); if(x==-1){ //当距离为-1表示两点之间没有直接通路 digit[0] = -1; size = 1; } else{ do{ digit[size++] = x%10000; x = x/10000; }while(x!=0); } } bigInteger operator * (int x) const{ int carry = 0; bigInteger ret; ret.init(); for(int i=0; i<size; i++){ ret.digit[ret.size++] = (digit[i]*x+carry)%10000; carry = (digit[i]*x+carry)/10000; } 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++){ ret.digit[ret.size++] = (digit[i]+A.digit[i]+carry)%10000; carry = (digit[i]+A.digit[i]+carry)/10000; } if(carry!=0){ ret.digit[ret.size++] = carry; } return ret; } int operator % (int x) const{ int remain = 0; for(int i=size-1; i>=0; i--){ int temp = remain*10000+digit[i]; remain = temp%x; } return remain; } 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]; } return digit[0]<A.digit[0]; } } }cost[501]; struct E{ //用于存储邻接链表的节点 int next; //与节点相邻的节点编号 bigInteger c; //与节点相邻的节点next和本节点之间的权值 }; vector<E> edge[501]; //邻接链表 bool mark[101]; //标记,当mark[j]为true时,表示结点j的最短路径长度已经得到,该结点已经加入集合k; bigInteger dist[101]; //距离向量,当mark[i]为true时,表示已得的最短路径长度;否则,表示所有从开始结点出发,经过已知的最短路径达到集合k中的某结点,再经过一条边到达结点i的路径中最短的距离。 int main(int argc, const char * argv[]) { int M,N; while (scanf("%d%d", &N, &M)!=EOF){ for (int i=0; i<501; i++) { edge[i].clear(); } for (int i=0; i<101; i++) { dist[i].init(); dist[i].set(-1); mark[i] = false; } cost[0].set(1); cost[1].set(2); for(int i=0; i<M; i++){ int a,b; scanf("%d%d", &a, &b); if (i>1) { cost[i] = cost[i-1]*2; } E temp; temp.next = b; temp.c = cost[i]; edge[a].push_back(temp); temp.next = a; edge[b].push_back(temp); } mark[0] = true; int newP = 0; //集合中新加入的点为0; dist[0].set(0); for(int j = 1; j<N; j++){ for(int i=0; i<edge[newP].size(); i++){ int t = edge[newP][i].next; //与新加入的结点相邻的结点 bigInteger cc = edge[newP][i].c; //与新加入的结点相邻结点的权值 if (mark[t]==true) { //如果与新加入的结点相邻的结点已经在集合k,则跳过 continue; } bigInteger temp; temp = dist[newP]+cc; if(dist[t].digit[0]==-1||temp<dist[t]) //如果与新加入的结点相邻的结点之前不可达,或者通过新加入的结点到达的距离更短,则更新距离 dist[t] = temp; } bigInteger min; min.size = 1001; for (int i=0; i<1001; i++) { //最小值初始化为一个大整数,为找最小值做准备 min.digit[i] = 9999; } for (int i=1; i<=N; i++) { //遍历所有结点,找到还未放入集合k,且距离最小的结点设置为newP if (mark[i]==true||dist[i].digit[0]==-1) { continue; } if (dist[i]<min) { min = dist[i]; newP = i; } } mark[newP] = true; //把newP放入集合k } for (int i=1; i<N; i++) { //按照题目输出到所有结点的距离 printf("%d\n", dist[i]%100000); } } return 0; }
相关文章推荐
- DFS求起点到终点最短路径,手动输入地图,5行4列,地图如下,起点(1,1)终点(4,3) 1是障碍 0是通路
- 最短路径算法之Floyd
- 关于象棋最短路径的一个问题
- PAT 1003. Emergency (25)(俩点间最短路径)
- 次最短路径 POJ 3255 Roadblocks
- hdu(2112)最短路径问题
- 最短路径算法Dijkstra和A*
- 图的最短路径问题
- Hadoop生态圈技术光速入门(最短路径算法MR实现、社交好友推荐算法)
- 看数据结构写代码(48) 弗洛伊德最短路径
- 最短路径
- AOJ GRL_1_A: Single Source Shortest Path (Dijktra算法求单源最短路径,邻接表)
- 最短路径算法
- Dijkstra算法和Floyd算法(单源最短路径)
- POJ3268---Silver Cow Party (最短路径)
- 图论02—随意两点间最短距离及路径(经典)
- 【模板】单源最短路径*
- 6.2--Dijkstra单源最短路径
- Dijkstra Bellman-Ford SPFA 几种最短路径求法 基本理论
- 九度OJ 1162:I Wanna Go Home(我想回家) (最短路径)