2014-12-26数据结构上机 解题报告
来源:互联网 发布:c语言编程需要什么软件 编辑:程序博客网 时间:2024/06/07 05:17
也快期末考了,所以写点数据机构上机的解题报告,和一些思想,帮助一下大家复习,也帮助我自己复习一下。
首先Problem A的意思是给你一个有向的图,然后让你判断这个图上面是否有环。
我们第十一章的作业题里面,有一道题就是判断无向图是否有环的。
这两道题都可以是采用深度优先搜索(DFS)解决。dfs(u)表示我们传进去一个点u,u的所有边。c[]数组表示DFS过程中结点访问的状态,即c[u] = -1 表示该结点正在访问, c[u] = 1表示该结点已经被访问, c[u] = 0 表示结点没有被访问。那么在DFS过程中如果出现了c[v] == -1,就代表着出现了环。如果看不懂参考着代码来看。
详细看下面代码:
#include <iostream>#include <cstring> using namespace std; const int MAXN = 2505;int c[MAXN]; int G[MAXN][MAXN]; // 用数组表示图 G[u][v] = 1 说明 有一条 u->v 的边int n, m;int T;bool dfs(int u) // DFS{ c[u] = -1; //标记u结点正在访问 for (int v = 1; v <= n; ++v) // 遍历u的所有边 if (G[u][v]) // 如果u->v有边 { if (c[v] == -1) return false; // 说明这里的v结点在较早之前已经被标记了,也就说明存在一个环使得 v->...->u->v;有环return false else if (!c[v] && !dfs(v)) return false; //!c[v] 为真是说c[v] == 0,也就是u没被访问过,那么就要进行dfs(v),如果dfs(v)返 //回false说明有环,那么就又直接返回false } c[u] = 1; //遍历完所有u的边后,就把u标记为已访问 return true; // 说明没发现环,返回 true} bool hasCycle() // 返回值依旧是颠倒是否,返回false说明有环,返回true说明无环。{ /*对于所有结点,都要进行DFS,因为①图可能不连通;②因为是有向的,环的起点可能不同。*/ for (int u = 1; u <= n; u++) if (!c[u]) if (!dfs(u)) return false; return true;} int main(){ cin >> T; while (T--) { cin >> n >> m; memset(G, 0, sizeof(G)); //初始化所有点都不连通。 memset(c, 0, sizeof(c)); //初始化所有点都未访问。 int u, v; for (int i = 0; i < m; ++i) { // 输入边 cin >> u >> v; G[u][v] = 1; } if (hasCycle()) cout << "NO" << endl; //这里颠倒是非的小细节不要在意 :) else cout << "YES" << endl; } return 0;}/************************************************************** Problem: 2298 User: 201330571073 Language: C++ Result: Accepted Time:32 ms Memory:26000 kb****************************************************************/
Problem B: Shortest Path
到目前为止,我都认为测试数据是错的,就又想上次那个链表题一样过不了。这道题的意思是给你一个无向图G,一个起点S,一个终点T,让你找到从S到T的最短路径。
就是基础的单源最短路,用Dijkstra解决
Dijkstra的思想在书本上已经有讲,我讲不一定比它清楚,就不讲了。
下面给出我写Dijkstra的写法,也就是《算法竞赛入门经典》里面的写法。
#include <iostream>#include <cstring>using namespace std;#define INF 0x3f3f3f3f //定义无穷变量的一种机智的方法,可以百度了解一下0x3f3f3f3fint N, C, S, T; int w[2505][2505]; // w[i][j] = INF 表示 i没有直接到j的边 w[i][j] = x表示 i到j有一条权值为x的边。int d[2505], v[2505]; // d[t] 表示 起点 s 到 t 的距离。 v[]是一个标记数组。void dij(int s) // s 表示 图的起点。{memset(v, 0, sizeof(v)); // 清除所有点的标记for (int i = 1; i <= N; ++i) d[i] = (i == s ? 0 : INF); // 初始化d[s]的=0, 其他d[i] = INF;for (int i = 1; i <= N; ++i) { // 循环遍历所有点。int x, m = INF;for (int y = 1; y <= N; ++y) // 在所有为标记的点中,选出 d值最小的结点xif (!v[y] && d[y] <= m)m = d[x = y];v[x] = 1; // 给结点 x 标记for (int y = 1; y <= N; ++y) // 对于从 x 出发的所有边(x,y)更新d[y] = min {d[y], d[x] + w(x,y)};if (w[x][y] < INF && d[x] < INF && d[y] > d[x] + w[x][y]) //这里我加入了w[][]和d[]无穷大,防止后面的相加溢出。 { d[y] = d[x] + w[x][y];}}}int main(){cin >> N >> C >> S >> T;for (int i = 1; i <= N; ++i) { // 初始化所有点不连通for (int j = 1; j <= N; ++j) {w[i][j] = INF;}}int u, v, c;for (int i = 0; i < C; ++i) {cin >> u >> v >> c;if (c < w[u][v]) w[u][v] = w[v][u] = c; //由于是无向图,所以要求设置 u->v 和 v->u都有边。}dij(S); cout << d[T] << endl;return 0;}
如果还有不懂,可以问我。
如果有错,希望指出。
谢谢大家。
0 0
- 2014-12-26数据结构上机 解题报告
- 北京航空航天大学2014第二次上机解题报告
- 北京航空航天大学2014第三次上机解题报告
- 北京航空航天大学2014第四次上机解题报告
- 北京航空航天大学2014第五次上机解题报告
- 北京航空航天大学2014第六次上机解题报告
- 2005浙大上机复试解题报告
- 2006浙大上机复试解题报告
- 2007浙大上机复试解题报告
- 2008浙大上机复试解题报告
- 2009浙大上机复试解题报告
- 2010浙大上机复试解题报告
- 【作业解答】第一次上机作业解题报告
- 【作业解答】第二次上机作业解题报告
- 【作业解答】第三次上机作业解题报告
- 15级算法第一次上机解题报告
- 15级算法第二次上机解题报告
- 16级C++第一次上机解题报告
- 卸载Mac osx上的JDK 1.7.x,并恢复至自带的1.6版本
- Java String之String和CharSequence、StringBuilder和StringBuffer的区别(3)
- html与javascript之网络篇
- git常用命令总结
- apue学习第三天——深度解析apue第三版示例程序编译问题
- 2014-12-26数据结构上机 解题报告
- JDK1.6官方下载_JDK6官方下载_JDK1.6API(chm)下载_JDK6APICHM中文参考
- sizeof
- 时间倒计时
- Java String之StringBuilder以及它的API的详细使用方法
- 题目1079:手机键盘
- 第2章 变量和基本类型 课后习题
- linux修改数据库密码
- 【转】DataGridView列的宽度、行的高度自动调整