hdu 3790 最短路径问题 (dijkstra算法+memset()用法)
来源:互联网 发布:mac os 10.13 cdr 编辑:程序博客网 时间:2024/06/05 11:01
最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8186 Accepted Submission(s): 2442
Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 21 2 5 62 3 4 51 30 0
Sample Output
9 11
Source
浙大计算机研究生复试上机考试-2010年
错了那么多次,重写了那么多次,看到别人解题报告,说如果距离一样,花费不要覆盖,全是错的。
我的错误竟然是忘记最后比较时标记vis数组是否访问,伤心啊,简单的错误挂了一天。。。
另外很疑惑memset()标记的时间为什么比双重for循环还浪费时间,大神blog说效率高啊!
memset()具体实现 参见blog:http://blog.csdn.net/hackbuteer1/article/details/7343189
memset()的效率以及源码分析
分类: 面试珠玑 2012-03-11 23:11 1926人阅读 评论(0)收藏举报
化工ccache编程优化测试
void *memset(void *s, int ch, size_t n);
作用:将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作。
不知道有没有像我一样把memset当作万能的初始化工具,例如:
int arr[n];
memset(arr,1,n*sizeof(int));
这样得到的arr数组一定不是全0,而是16843009,下面解释原因。
首先,变量类型的本质只是标志从某一内存地址开始读取的位数,强制转换就是改变读取位数的大小。
第3行把int类型的c转换成unsigned char类型,意味着截去c的高24位,只保留低8位。第4行把s当作unsigned char*类型,也就是说su中的每一个元素按8位计算。
现在来看看文章开头的那个代码会做什么。
c的二进制 : 00000000000000000000000000000001(32位)
1、c转换为unsigned char 后:00000001(8位)
2、将指针su(unsigned char类型)的每一元素(8位)赋值为00000001,循环4n次。
3、memset()结束后,arr的每个元素按照int类型读取,读出来的就是1000000010000000100000001,十进制就是16843009。
不过如果是memset(arr,0,n*sizeof(int));的话可以使用,因为32位都是0
再来说memset()的效率问题。使用memset函数与将上面的函数代码写在自己的程序里是不一样的,C标准库中的memset对Cache的利用做了优化,具体的在《C专家编程》151页有解释(其实是我没看懂),这里给出测试:程序里的注释部分与memset行分别使用,结果是使用memset的程序运行时间大约为0.1s,而用for循环的程序要3s多。
综上:memset()可以用在字符数组的初始化以及类似于memset(arr,0,n*sizeof(int));的情况,效率比手动赋值要高的多。
作用:将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作。
不知道有没有像我一样把memset当作万能的初始化工具,例如:
int arr[n];
memset(arr,1,n*sizeof(int));
这样得到的arr数组一定不是全0,而是16843009,下面解释原因。
首先,变量类型的本质只是标志从某一内存地址开始读取的位数,强制转换就是改变读取位数的大小。
下面来看memset的实现:(代码来自《C标准库》P398)
- void *(memset) (void *s,int c,size_t n)
- {
- const unsigned char uc = c;
- unsigned char *su;
- for(su = s;0 < n;++su,--n)
- *su = uc;
- return s;
- }
现在来看看文章开头的那个代码会做什么。
c的二进制 : 00000000000000000000000000000001(32位)
1、c转换为unsigned char 后:00000001(8位)
2、将指针su(unsigned char类型)的每一元素(8位)赋值为00000001,循环4n次。
3、memset()结束后,arr的每个元素按照int类型读取,读出来的就是1000000010000000100000001,十进制就是16843009。
不过如果是memset(arr,0,n*sizeof(int));的话可以使用,因为32位都是0
再来说memset()的效率问题。使用memset函数与将上面的函数代码写在自己的程序里是不一样的,C标准库中的memset对Cache的利用做了优化,具体的在《C专家编程》151页有解释(其实是我没看懂),这里给出测试:
- #include <string.h>
- #define MAXSIZE 100000
- int main()
- {
- char arr[MAXSIZE];
- for(int i=0;i<10000;i++)
- {
- memset(arr,'0',sizeof(arr));
- // for(int j=0;j<MAXSIZE;j++)
- // arr[0] = '0';
- }
- return 0;
- }
综上:memset()可以用在字符数组的初始化以及类似于memset(arr,0,n*sizeof(int));的情况,效率比手动赋值要高的多。
代码:
#include<cstdio>#include<cstring>using namespace std;const int maxn = 0x7fffffff;int cost[1005][1005],len[1005][1005],dis[1005],val[1005],vis[1005];int n,m,s,e;void dijkstra(){memset(vis,0,sizeof(vis));int min,cnt;for(int i=1;i<=n;i++){dis[i]=len[s][i];val[i]=cost[s][i];}dis[s]=val[s]=0;for(int i=1;i<=n;i++){min=maxn,cnt=-1;for(int j=1;j<=n;j++)if(!vis[j] && min>dis[j])min=dis[cnt=j];vis[cnt]=1;for(int j=1;j<=n;j++){if(!vis[j]&&len[cnt][j]<maxn){if(dis[j]>dis[cnt]+len[cnt][j]){dis[j]=dis[cnt]+len[cnt][j];val[j]=val[cnt]+cost[cnt][j];}else if(dis[j]==dis[cnt]+len[cnt][j] && val[j]>val[cnt]+cost[cnt][j])val[j]=val[cnt]+cost[cnt][j];}}}}int main(){int a,b,c,d;while(scanf("%d%d",&n,&m)&&(n||m)){//for(int i=1;i<=n;i++)//for(int j=1;j<=n;j++)//{//cost[i][j]=maxn;//len[i][j]=maxn; //}memset(cost,127,sizeof(cost));memset(len,127,sizeof(len));for(int i=0;i<m;i++){scanf("%d%d%d%d",&a,&b,&c,&d);if(len[a][b]>c){len[a][b]=len[b][a]=c;cost[a][b]=cost[b][a]=d;}else if(len[a][b]==c && cost[a][b]>d)cost[a][b]=cost[b][a]=d;}scanf("%d%d",&s,&e);dijkstra();printf("%d %d\n",dis[e],val[e]);}return 0;}
- hdu 3790 最短路径问题 (dijkstra算法+memset()用法)
- HDU--3790:最短路径问题 (Dijkstra算法)
- 最短路径问题 HDU杭电3790 【Dijkstra算法】
- HDU 3790 最短路径问题(双重Dijkstra算法)
- HDU 3790 最短路径问题 (Dijkstra算法)
- hdu 3790 最短路径问题 dijkstra算法
- 最短路径 Dijkstra 算法 HDU 3790
- HDU 3790 最短路径问题(Dijkstra)
- HDU--3790最短路径问题 【Dijkstra】
- hdu 3790 最短路径问题(Dijkstra)
- HDU 3790:最短路径问题【Dijkstra】
- HDU-3790 最短路径问题(Dijkstra)
- HDU 3790 最短路径问题(dijkstra)
- HDU 3790 最短路径问题【多关键字最短路,Dijkstra算法+spfa算法】
- hdu 3790 最短路径问题 最短路Dijkstra
- HDU 3790 最短路径问题【最短路 dijkstra 双权值】
- HDU 3790.最短路径问题【最短路径Dijkstra算法】【4月14】
- hdu 2066最短路径(Dijkstra算法)
- 为什么Java byte 类型的取值范围是-128~127
- python循环for,range,xrange;while
- hdu 4611 Balls Rearrangement 多校第二场
- GCD 扩展GCD 快速GCD 模线性方程 模线性方程组 单独求欧拉函数 递推求欧拉函数
- 贪心——NYOJ 题目236 心急的C小加
- hdu 3790 最短路径问题 (dijkstra算法+memset()用法)
- POJ 2954 Triangle (pick 定理)
- 安卓调试时ADB server didn't ACK的终极解决办法
- 马的走法
- 配置普通用户有使用sudo命令的权限
- Android apk反编译和odex转dex
- XMPP协议的原理介绍
- hdu 2870
- 文件锁(Filelock) 与锁定映射文件部分内容