九度oj 题目1100:最短路径

题目描述:

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这道题考了最短路径算法和大数运算,好歹做出来了
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <string>
  5 #include <cmath>
  6 #include <algorithm>
  7
  8 #define MAX 102
  9 #define TENLEN 200
 10 #define modN 100000
 11 using namespace std;
 12
 13 int flag[MAX];
 14 int k2[TENLEN];
 15 int minDis[TENLEN];
 16 int dis[TENLEN];
 17
 18 struct Node
 19 {
 20     int dis[TENLEN];
 21     int zhi;
 22 };
 23
 24 int graph[MAX][MAX];
 25 Node map[MAX][MAX];
 26 Node lowCost[MAX];
 27
 28 void calSum(int sum[], int a[], int b[]) {
 29     int ci = 0;
 30     for(int i = 0; i < TENLEN;i++) {
 31         int ben = (a[i] + b[i] + ci) % 10;
 32         ci = (a[i] + b[i] + ci)/10;
 33         sum[i] = ben;
 34    }
 35 }
 36
 37 int cmp(int a[], int b[]) {
 38     for(int i = TENLEN-1; i >= 0; i--) {
 39         if(b[i] > a[i]) {
 40             return -1;
 41         }
 42         else if(a[i] > b[i]) {
 43             return 1;
 44         }
 45     }
 46     return 0;
 47 }
 48
 49 int copy(int a[], int b[]) {
 50     for(int i = 0; i < TENLEN; i++) {
 51         b[i] = a[i];
 52     }
 53 }
 54
 55
 56 void modNprint(int a[]) {
 57     bool isBegin = false;
 58     for(int i = 4; i >= 0; i--) {
 59         if(!isBegin && a[i] != 0) {
 60             isBegin = true;
 61             printf("%d", a[i]);
 62         }
 63         else if(isBegin){
 64             printf("%d", a[i]);
 65         }
 66     }
 67     if(!isBegin) {
 68         printf("0");
 69     }
 70     printf("\n");
 71 }
 72
 73 void print(int a[]) {
 74     bool isBegin = false;
 75     for(int i = TENLEN - 1; i >= 0; i--) {
 76         if(!isBegin && a[i] != 0) {
 77             isBegin = true;
 78             printf("%d", a[i]);
 79         }
 80         else if(isBegin){
 81             printf("%d", a[i]);
 82         }
 83     }
 84     if(!isBegin) {
 85         printf("0");
 86     }
 87     printf("\n");
 88 }
 89 int main(int argc, char const *argv[])
 90 {
 91     int n, m;
 92     //freopen("input.txt","r",stdin);
 93     while(scanf("%d %d",&n,&m) != EOF) {
 94         memset(k2, 0, sizeof(k2));
 95         k2[0] = 1;
 96         for(int i = 0; i < n; i++) {
 97             for(int j = 0; j < n; j++) {
 98                 graph[i][j] = 0;
 99             }
100         }
101         for(int i = 0; i < m; i++) {
102             int atemp, btemp;
103             scanf("%d %d",&atemp,&btemp);
104             copy(k2, map[atemp][btemp].dis);
105             copy(k2, map[btemp][atemp].dis);
106             graph[atemp][btemp] = 1;
107             graph[btemp][atemp] = 1;
108             calSum(k2, k2, k2);
109             //print(k2);
110         }
111
112         memset(flag, 0, sizeof(flag));
113         flag[0] = 1;
114         for(int i = 0; i < n; i++) {
115             if(graph[0][i] == 1) {
116                 copy(map[0][i].dis,lowCost[i].dis);
117             }
118         }
119
120
121         for(int i = 1; i < n; i++) {
122             for(int j = 0; j < TENLEN; j++) {
123                 minDis[j] = 9;
124             }
125             int min = -1;
126
127             for(int j = 1; j < n; j++) {
128                 if(flag[j] == 0 && graph[0][j] == 1) {
129
130                     if(cmp(minDis, lowCost[j].dis) == 1) {
131                         copy(lowCost[j].dis,minDis);
132                         //print(minDis);
133                         //print(lowCost[j].dis);
134                         min = j;
135                     }
136                 }
137             }
138             //printf("min is %d\n",min);
139             if(min != -1) {
140                 flag[min] = 1;
141                 for(int j = 0; j < n; j++) {
142                     if(flag[j] == 0 && graph[min][j] == 1 ) {
143                         calSum(dis, lowCost[min].dis, map[min][j].dis);
144                        if(graph[0][j] == 0 || cmp(dis,lowCost[j].dis) == -1) {
145                             graph[0][j] = 1;
146                             copy(dis,lowCost[j].dis);
147                         }
148                     }
149
150                 }
151             }
152         }
153         for(int i = 1; i < n; i++) {
154             if(graph[0][i] == 1) {
155                 modNprint(lowCost[i].dis);
156             }
157             else {
158                 puts("-1");
159             }
160
161         }
162     }
163     return 0;
164 }

占用的内存略大,还需要再精简

时间: 2024-11-09 10:26:01

九度oj 题目1100:最短路径的相关文章

九度oj 题目1007:奥运排序问题

九度oj 题目1007:奥运排序问题   恢复 题目描述: 按要求,给国家进行排名. 输入:                        有多组数据. 第一行给出国家数N,要求排名的国家数M,国家号从0到N-1. 第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万). 接下来一行给出M个国家号. 输出:                        排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例 对每个国家给出最佳排名排名方式 和 最终排名 格式为: 排名:排名

九度oj 题目1546:迷宫问题 (概率dp guess消元)

题目链接:点击打开链接 题目描述: 给定一个n*m的迷宫,如 S.. ..# E.E 其中,S代表开始位置,#代表不可行走的墙,E代表出口. 主人公从开始位置出发,每次等概率的随机选择下一个可以行走的位置,直到到达某一个出口为止. 现在他想知道,在这一概率事件中,它从开始位置走到某一个出口的期望步数是多少. 输入: 输入包含多组测试用例,每组测试用例由两个整数n,m(1<=n,m<=15)开始,代表迷宫的大小 接下去n行每行m个字符描述迷宫信息,具体规则如题面所述. 数据保证至少存在一个E和一

九度oj题目1009:二叉搜索树

题目描述: 判断两序列是否为同一二叉搜索树序列 输入:                        开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树. 接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树. 输出:                        如果序列相同则输出YES,否则输出NO 样

九度oj 题目1171:C翻转

题目描述: 首先输入一个5 * 5的数组,然后输入一行,这一行有四个数,前两个代表操作类型,后两个数x y代表需操作数据为以x y为左上角的那几个数据. 操作类型有四种:  1 2 表示:90度,顺时针,翻转4个数  1 3 表示:90度,顺时针,翻转9个数  2 2 表示:90度,逆时针,翻转4个数  2 3 表示:90度,逆时针,翻转9个数 输入: 输入有多组数据. 每组输入一个5 * 5的数组,然后输入一行,这一行有四个数,前两个代表操作类型,后两个数x y代表需操作数据为以x y为左上角

九度oj 题目1151:位操作练习

题目描述: 给出两个不大于65535的非负整数,判断其中一个的16位二进制表示形式,是否能由另一个的16位二进制表示形式经过循环左移若干位而得到. 循环左移和普通左移的区别在于:最左边的那一位经过循环左移一位后就会被移到最右边去.比如:1011 0000 0000 0001 经过循环左移一位后,变成 0110 0000 0000 0011, 若是循环左移2位,则变成 1100 0000 0000 0110 输入: 第一行是个整数n, 0 < n < 300000,表示后面还有n行数据 后面是n

九度oj 题目1495:关键点

题目描述: 在一个无权图中,两个节点间的最短距离可以看成从一个节点出发到达另一个节点至少需要经过的边的个数. 同时,任意两个节点间的最短路径可能有多条,使得从一个节点出发可以有多条最短路径可以选择,并且沿着这些路径到达目标节点所经过的边的个数都是一样的. 但是在图中有那么一些特殊的节点,如果去除这些点,那么从某个初始节点到某个终止节点的最短路径长度要么变长,要么这两个节点变得不连通.这些点被称为最短路径上的关键点. 现给定一个无权图,以及起始节点和终止节点,要求输出该图上,这对节点间最短路径上的

九度OJ—题目1032:ZOJ

题目描述: 读入一个字符串,字符串中包含ZOJ三个字符,个数不一定相等,按ZOJ的顺序输出,当某个字符用完时,剩下的仍然按照ZOJ的顺序输出. 输入: 题目包含多组用例,每组用例占一行,包含ZOJ三个字符,当输入"E"时表示输入结束. 1<=length<=100. 输出: 对于每组输入,请输出一行,表示按照要求处理后的字符串. 具体可见样例. 样例输入: ZZOOOJJJ ZZZZOOOOOJJJ ZOOOJJ E 样例输出: ZOJZOJOJ ZOJZOJZOJZOO

九度oj题目&amp;amp;吉大考研10年机试题全解

吉大考研机试2010年题目 题目一(jobdu1478:三角形的边).    http://ac.jobdu.com/problem.php?pid=1478 给出三个正整数,计算最小的数加上次小的数与最大的数之差. 题目分析: 简单题.能够用非常多方法解决 AC代码: #include<iostream> using namespace std; int main() {     int a,b,c,ma;     while(cin>>a>>b>>c){

九度oj 题目1552:座位问题

题目描述: 计算机学院的男生和女生共n个人要坐成一排玩游戏,因为计算机的女生都非常害羞,男生又很主动,所以活动的组织者要求在任何时候,一个女生的左边或者右边至少有一个女生,即每个女生均不会只与男生相邻.现在活动的组织者想知道,共有多少种可选的座位方案. 例如当n为4时,共有 女女女女, 女女女男, 男女女女, 女女男男, 男女女男, 男男女女, 男男男男7种. 输入: 输入包含多组测试用例,每组测试用例仅包含一个整数n(1<=n<=1000). 输出: 对于每组测试用例,输出一个数代表可选的方