博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uva 567(图论) + 图论入门算法分析
阅读量:5833 次
发布时间:2019-06-18

本文共 5623 字,大约阅读时间需要 18 分钟。

这道题的大致意思是给你一个有20个点的无向图,再给你最多100个查询。让你每次查询输出两个顶点之间的最短路径长度。

本题是最基础的图论题,解决方法有多种,下面我们列举若干种方法并结合其效率进行讨论:

一、简单BFS

这种算法是最基本的算法,对于任意两个点直接用广度优先搜索惊醒最短路径求解。写起来方便但是效率并不怎么高。

代码如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #define LEN 3011 using namespace std;12 13 int Map[LEN][LEN], vis[LEN], cnt = 1;14 15 typedef struct{16 int v, step;17 }P;18 19 int BFS(int st, int end)20 {21 queue

q;22 P ss;23 ss.v = st;24 ss.step = 0;25 vis[st] = 1;26 q.push(ss);27 while(!q.empty()){28 P vex = q.front();29 q.pop();30 if(vex.v==end){31 return vex.step;32 }33 for(int i=1; i<22; i++){34 P newv;35 newv.v = i;36 newv.step = vex.step+1;37 if(Map[vex.v][i]==1 && vis[i]==0){38 vis[i] = 1;39 q.push(newv);40 }41 }42 }43 return -1;44 }45 46 int main()47 {48 // freopen("in.txt", "r", stdin);49 50 int vex, n;51 while(scanf("%d", &n)!=EOF){52 //building Map53 memset(Map, 0, sizeof Map);54 for(int i=0; i

View Code

二、简单BFS+记忆化

上一种算法只要稍稍改进一下即可在时间效率上有不错的提升,首先我们从搜索过程中考虑在广度优先搜索中我们再求到最小值之前其实经过了很多节点,我们每到一个结点其实已经求出了起始点到他的最短路径。若是用一张表记录下来我们下次就可以不重复求解。这次程序中dis数组就起到了这个作用。若询问时dis[a][b]==-1则说明在以前没有求解过,需调用BFS。否则直接输出相应表项即可。

代码如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #define LEN 3011 12 using namespace std;13 14 int Map[LEN][LEN], vis[LEN], cnt = 1;15 int dis[LEN][LEN];16 17 typedef struct{18 int v, step;19 }P;20 21 int BFS(int st, int end)22 {23 queue

q;24 P ss;25 ss.v = st;26 ss.step = 0;27 vis[st] = 1;28 q.push(ss);29 while(!q.empty()){30 P vex = q.front();31 q.pop();32 if(dis[st][vex.v]==-1)dis[st][vex.v] = vex.step; //做记录33 if(vex.v==end){34 return vex.step;35 }36 for(int i=1; i<22; i++){37 P newv;38 newv.v = i;39 newv.step = vex.step+1;40 if(Map[vex.v][i]==1 && vis[i]==0){41 vis[i] = 1;42 q.push(newv);43 }44 }45 }46 return -1;47 }48 49 int main()50 {51 // freopen("in.txt", "r", stdin);52 53 int vex, n;54 while(scanf("%d", &n)!=EOF){55 //building Map56 memset(Map, 0, sizeof Map);57 memset(dis, -1, sizeof dis);58 for(int i=0; i<22; i++) dis[i][i] = 0;59 for(int i=0; i

View Code

三、dijkstra算法

本题边的权值均为1,用dij算法是大材小用了,但是从时间上看是n^3与前一算法大致一样。我用了n次dij就把任意两点之间的距离都求了出来最后只需查询dis数组即可得到答案。

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #define LEN 3011 #define INF 0x7fffffff12 using namespace std;13 14 int Map[LEN][LEN], dis[LEN][LEN], vis[LEN], cnt = 1;15 16 void init()17 {18 for(int i=0; i<=20; i++){19 for(int j=0; j<=20; j++)20 Map[i][j] = INF;21 Map[i][i] = 0;22 }23 memset(dis, 0, sizeof dis);24 }25 26 void Dijkstra(int vex)27 {28 memset(vis, 0, sizeof vis);29 for(int i=1; i<=20; i++)30 dis[vex][i] = Map[vex][i];31 vis[vex] = 1;32 for(int i=1; i<20 ;i++)33 {34 int min, mindis = INF;35 for(int j=1; j<=20; j++)36 if(dis[vex][j]
View Code

四、dijkstra算法+IO优化

第一次写IO优化表示只是读取正整数还是比较简单的。

代码如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #define LEN 3011 #define INF 0x7fffffff12 using namespace std;13 14 int Map[LEN][LEN], dis[LEN][LEN], vis[LEN], cnt = 1;15 16 void init()17 {18 for(int i=0; i<=20; i++){19 for(int j=0; j<=20; j++)20 Map[i][j] = INF;21 Map[i][i] = 0;22 }23 memset(dis, 0, sizeof dis);24 }25 26 void Dijkstra(int vex)27 {28 memset(vis, 0, sizeof vis);29 for(int i=1; i<=20; i++)30 dis[vex][i] = Map[vex][i];31 vis[vex] = 1;32 for(int i=1; i<20 ;i++)33 {34 int min, mindis = INF;35 for(int j=1; j<=20; j++)36 if(dis[vex][j]
'9');53 ret = 0;54 while(c>='0' && c<='9'){55 ret = ret*10+(c-'0');56 c = getchar();57 }58 }59 60 int main()61 {62 // freopen("in.txt", "r", stdin);63 64 int vex, n;65 while(scanf("%d", &n)!=EOF){66 //building Map67 init();68 for(int i=0; i
View Code

五、dijkstra算法+优先队列优化+IO优化

无聊的时候有换了O(mlogn)的Dij重写了一遍时间稳定在0.07左右,又快了一些。

代码如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #define LEN 3013 #define INF 0x7fffffff14 using namespace std;15 16 int dis[LEN][LEN], vis[LEN], cnt = 1;17 vector
Map[LEN];18 typedef pair
pii;19 20 void init()21 {22 for(int i=0; i
, greater
> q;30 for(int i=0; i<21; i++)dis[vex][i] = (i==vex?0:INF);31 memset(vis, 0, sizeof vis);32 q.push(make_pair(dis[vex][vex], vex));33 while(!q.empty()){34 pii u = q.top(); q.pop();35 int x = u.second;36 if(vis[x]) continue;37 vis[x] = 1;38 for(vector
::iterator it = Map[x].begin(); it!=Map[x].end(); ++it){39 if(dis[vex][*it]>dis[vex][x]+1) {40 dis[vex][*it] = dis[vex][x]+1;41 q.push(make_pair(dis[vex][*it], *it));42 }43 }44 }45 }46 47 inline void read(int &ret)48 {49 char c;50 while((c = getchar())<'0' || c>'9');51 ret = 0;52 while(c>='0' && c<='9'){53 ret = ret*10+(c-'0');54 c = getchar();55 }56 }57 58 int main()59 {60 // freopen("in.txt", "r", stdin);61 62 int vex, n;63 while(scanf("%d", &n)!=EOF){64 //building Map65 init();66 for(int i=0; i
View Code

 

转载于:https://www.cnblogs.com/shu-xiaohao/p/3440474.html

你可能感兴趣的文章
python debug
查看>>
java 连接数据库之一个完整的函数
查看>>
mysql脚本
查看>>
OllyDBG 入门系列教学--让你瞬间成为破解高手
查看>>
Dubbo点滴(2)之集群容错
查看>>
检测不到兼容的键盘驱动程序
查看>>
listbox用法
查看>>
冲刺第九天 1.10 THU
查看>>
传值方式:ajax技术和普通传值方式
查看>>
Linux-网络连接-(VMware与CentOS)
查看>>
寻找链表相交节点
查看>>
AS3——禁止swf缩放
查看>>
linq 学习笔记之 Linq基本子句
查看>>
[Js]布局转换
查看>>
Hot Bath
查看>>
国内常用NTP服务器地址及
查看>>
Java annotation 自定义注释@interface的用法
查看>>
Apache Spark 章节1
查看>>
phpcms与discuz的ucenter整合
查看>>
Linux crontab定时执行任务
查看>>