eulerianCycle.c

  1. What determines whether a graph is Eulerian or not?
  2. Write a C program that reads a graph, prints the graph, and determines whether an input graph is Eulerian or not.
    • if the graph is Eulerian, the program prints an Eulerian path

      • you should start with vertex 0
      • note that you may use the function findEulerianCycle() from the lecture on Graph Search Applications

    • if it is not Eulerian, the program prints the message Not Eulerian

For example,

  • The graph:

      #4
    0 1 0 2 0 3 1 2 2 3

    is not Eulerian (can you see why?). Using this as input, your program should output:

      V=4, E=5
    <0 1> <0 2> <0 3>
    <1 0> <1 2>
    <2 0> <2 1> <2 3>
    <3 0> <3 2>
    Not Eulerian
  • In the above-named lecture I showed a 'concentric squares' graph (called concsquares):

      #8
    0 7 7 5 5 1 1 0
    6 0 6 7
    2 5 2 7
    4 1 4 5
    3 0 3 1

    which is Eulerian, although I've labelled the vertices differently here. For this input your program should produce the output:

      V=8, E=12
    <0 1> <0 3> <0 6> <0 7>
    <1 0> <1 3> <1 4> <1 5>
    <2 5> <2 7>
    <3 0> <3 1>
    <4 1> <4 5>
    <5 1> <5 2> <5 4> <5 7>
    <6 0> <6 7>
    <7 0> <7 2> <7 5> <7 6>
    Eulerian cycle: 0 1 4 5 2 7 5 1 3 0 6 7 0

    Draw concsquares, label it as given in the input file above, and check the cycle is indeed Eulerian.

  • The function findEulerCycle() in the lecture notes does not handle disconnected graphs. In a disconnected Eulerian graph, each subgraph has an Eulerian cycle.

    • Modify this function to handle disconnected graphs.
    • With this change, your program should now work for the graph consisting of 2 disconnected triangles:
         #6
      0 1 0 2 1 2 3 4 3 5 4 5

      It should now find 2 Eulerian paths:

         V=6, E=6
      <0 1> <0 2>
      <1 0> <1 2>
      <2 0> <2 1>
      <3 4> <3 5>
      <4 3> <4 5>
      <5 3> <5 4>
      Eulerian cycle: 0 1 2 0
      Eulerian cycle: 3 4 5 3

思路:经过一条边就删掉一个,通过遍历查找是否遍历完(针对不连通的graph)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "Graph.h"
#include "Quack.h" #define UNVISITED -1
#define WHITESPACE 100 void dfsR(Graph g, Vertex v, int numV, int *order, int *visited);
Vertex getAdjacent(Graph g, int numV, Vertex v); int readNumV(void) { // returns the number of vertices numV or -1
int numV;
char w[WHITESPACE];
scanf("%[ \t\n]s", w); // skip leading whitespace
if ((getchar() != '#') ||
(scanf("%d", &numV) != 1)) {
fprintf(stderr, "missing number (of vertices)\n");
return -1;
}
return numV;
} int readGraph(int numV, Graph g) { // reads number-number pairs until EOF
int success = true; // returns true if no error
int v1, v2;
while (scanf("%d %d", &v1, &v2) != EOF && success) {
if (v1 < 0 || v1 >= numV || v2 < 0 || v2 >= numV) {
fprintf(stderr, "unable to read edge\n");
success = false;
}
else {
insertE(g, newE(v1, v2));
}
}
return success;
} void findEulerCycle(Graph g, int numV, Vertex startv) {
Quack s = createQuack();
push(startv, s); int allVis = 0;
while (!allVis) {
printf("Eulerian cycle: ");
while (!isEmptyQuack(s)) {
Vertex v = pop(s); // v is the top of stack vertex and ...
push(v, s); // ... the stack has not changed
Vertex w;
if ((w = getAdjacent(g, numV, v)) >= 0) {
push(w, s); // push a neighbour of v onto stack
removeE(g, newE(v, w)); // remove edge to neighbour
}
else {
w = pop(s);
printf("%d ", w);
}
}
printf("\n");
allVis = 1; for (Vertex v = 0; v < numV && allVis; v++) {
for (Vertex w = 0; w < numV && allVis; w++) {
if (isEdge(g, newE(v, w))) {
allVis = 0;
push(v, s);
}
}
}
}
} Vertex getAdjacent(Graph g, int numV, Vertex v) {
// returns the Largest Adjacent Vertex if it exists, else -1
Vertex w;
Vertex lav = -1; // the adjacent vertex
for (w=numV-1; w>=0 && lav==-1; w--) {
Edge e = newE(v, w);
if (isEdge(g, e)) {
lav = w;
}
}
return lav;
} int isEulerian(Graph g, int numV) {
int count = 0;
for (Vertex w = 0; w < numV; w++) {
count = 0;
for (Vertex v = 0; v < numV; v++) {
if (isEdge(g, newE(w, v))) {
count++;
}
}
if (count % 2 != 0) {
return 0;
}
}
return 1;
} int main (void) {
int numV;
if ((numV = readNumV()) >= 0) {
Graph g = newGraph(numV);
if (readGraph(numV, g)) {
showGraph(g); if(isEulerian(g, numV)) {
findEulerCycle(g, numV, 0);
}
else {
printf("Not Eulerian\n");
}
}
}
else {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
} // clear && gcc dfs_EulerCycle.c GraphAM.c Quack.c && ./a.out < input_1.txt // clear && gcc dfs_EulerCycle.c GraphAM.c Quack.c && ./a.out < input_2.txt // clear && gcc dfs_EulerCycle.c GraphAM.c Quack.c && ./a.out < input_3.txt

unreachable.c

Write a program that uses a fixed-point computation to find all the vertices in a graph that are unreachable from the start vertex (assume it to be 0). Note the following:

  • the fixed-point computation should be iterative
  • you should not use recursion, or stacks or queues

If a graph is disconnected:

  • then those vertices not reachable (say vertices 8 and 9) should be output as follows:

     Unreachable vertices = 8 9

If a graph is connected then all vertices are reachable and the output is :

  •  Unreachable vertices = none

For example:

  • Here is a graph that consists of 2 disconnected triangles:

     #6
    0 1 0 2 1 2 3 4 3 5 4 5

    If the start vertex is 0, then the output should be:

     V=6, E=6
    <0 1> <0 2>
    <1 0> <1 2>
    <2 0> <2 1>
    <3 4> <3 5>
    <4 3> <4 5>
    <5 3> <5 4>
    Unreachable vertices = 3 4 5

    because obviously the vertices in the second triangle are not reachable from the first.

  • here is a connected graph:
     #5
    0 1 1 2 2 3 3 4 4 0
    1 3 1 4
    2 4

    Starting at any vertex, the result should be:

     V=5, E=8
    <0 1> <0 4>
    <1 0> <1 2> <1 3> <1 4>
    <2 1> <2 3> <2 4>
    <3 1> <3 2> <3 4>
    <4 0> <4 1> <4 2> <4 3>
    Unreachable vertices = none

思路:

  • 首先就是设置 outside数组,默认是都为 -1,一旦被访问了就赋值为 0,变为 inside
  • 设置一个 changing 字符串,用来监测 outside 数组是否有变化
  • 如果变化的话,就遍历所有inside的点的相连接的点,如果发现 outside,则将此点赋值为 inside,changing 赋值为1
  • while 循环,继续遍历,知道所有 inside 点的邻接点都是 inside,遍历结束
  • 因此会将所有一个连通图中的点放入在 inside 内部
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "Graph.h" #define UNVISITED -1
#define WHITESPACE 100 int readNumV(void) { // returns the number of vertices numV or -1
int numV;
char w[WHITESPACE];
scanf("%[ \t\n]s", w); // skip leading whitespace
if ((getchar() != '#') ||
(scanf("%d", &numV) != 1)) {
fprintf(stderr, "missing number (of vertices)\n");
return -1;
}
return numV;
} int readGraph(int numV, Graph g) { // reads number-number pairs until EOF
int success = true; // returns true if no error
int v1, v2;
while (scanf("%d %d", &v1, &v2) != EOF && success) {
if (v1 < 0 || v1 >= numV || v2 < 0 || v2 >= numV) {
fprintf(stderr, "unable to read edge\n");
success = false;
}
else {
insertE(g, newE(v1, v2));
}
}
return success;
} int *mallocArray(int numV) {
int *array = malloc(numV * sizeof(int));// l
if (array == NULL) { // o
fprintf(stderr, "Out of memory\n"); // c
exit(1); // a
} // l
int i; // f
for (i=0; i<numV; i++) { // u
array[i] = UNVISITED; // n
} // c
return array; // t
} void showUnreach(Graph g, int numV, Vertex startv) {
int *outside = mallocArray(numV);
outside[startv] = 0;
int changing = 1;
while (changing) {
changing = 0;
for (Vertex v = 0; v < numV; v++) {
if (!outside[v]) {
for (Vertex w = 0; w < numV; w++) {
if (isEdge(g, newE(v, w)) && outside[w] == UNVISITED) {
outside[w] = 0;
changing = 1;
}
}
}
}
}
printf("Unreachable vertices = ");
int any = 0;
for (Vertex v = 0; v < numV; v++) {
if (outside[v] == UNVISITED) {
printf("%d ", v);
any = 1;
}
}
if (!any) {
printf("none");
}
putchar('\n');
return;
} int main (void) {
int numV;
if ((numV = readNumV()) >= 0) {
Graph g = newGraph(numV);
if (readGraph(numV, g)) {
showGraph(g);
showUnreach(g, numV, 0);
}
}
else {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
} // clear && gcc unreachable.c GraphAM.c && ./a.out < input_1.txt // clear && gcc unreachable.c GraphAM.c && ./a.out < input_2.txt // clear && gcc unreachable.c GraphAM.c && ./a.out < input_3.txt

【432】COMP9024,Exercise9的更多相关文章

  1. 【Demo】QQ,github,微博第三方社交登录

    本文主要讲解 集成 第三方社交账号登录 为什么会有这个需求? 主要是因为目前互联网的网站数量太多,如果在各个站点都注册一个账号 用户非常不容易记住每个账号的用户名和密码,并且非常难保证每个账号的密码足 ...

  2. 【MVC】 js,css 压缩

    [MVC] js,css 压缩 一. 引用 System.Web.Optimization.dll : 使用 Nuget ,在控制台输入 Install-Package Microsoft.AspNe ...

  3. 关于【bootstrap】中,【tooltip】的不算bug的bug的个人看法

    先说下遇到这个问题的背景吧. 就是在页面中有个div,这个div右上角(或者其他位置)有个 × 的图标(这个图标添加tooltip工具提示),光标移到这个图标时,触发tooltip,提示“点击移除”这 ...

  4. Switch选择语句能否作用在String【字符串】上,也就是能否这么写:Switch(一个字符串变量)?

    Switch选择语句能否作用在String[字符串]上,也就是能否这么写:Switch(一个字符串变量)? 解答:不可以,只能处理int,byte,short,char,(其实是只能处理int,其它三 ...

  5. 【多线程】 Task ,async ,await

    [多线程]Task ,async ,await 一. WinForm 里经常会用到多线程, 多线程的好出就不多说了,来说说多线程比较麻烦的地方 1. UI 线程与其他线程的同步,主要是 Form 和 ...

  6. 【题解】Leyni,罗莉和队列(树状数组)

    [题解]Leyni,罗莉和队列(树状数组) HRBUST - 1356 将整个序列reverse一下,现在就变成了从高到低的排队.题目就变成了,定位一个妹子,问这个妹子前面的比这个妹子小的妹子中,下标 ...

  7. 【javascript】您好, 您要的ECMAScript6速记套餐到了

    [前言]本文“严重参考” 自阮一峰老师写的文档,在此我郑重感谢他沉默无声的帮助 总结一下ES6为 javascript中的 对象/数组/函数 这JS三巨头所提供的更简洁优雅的书写方式,以及扩展的API ...

  8. 【转载】通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?

    本文转载自:http://www.cnblogs.com/1996V/p/9037603.html [尊重作者原创,转载说明出处!感谢作者“小曾看世界”分享! ] 什么是.NET?什么是.NET Fr ...

  9. 【npm】伙计,给我来一杯package.json!不加糖

    前言:夜深了,我熬了一锅热气腾腾的package.json,给大家端上来,希望大家喜欢 json和JS对象的区别 package.json,顾名思义,它是一个json文件,而不能写入JS对象. 所以我 ...

随机推荐

  1. 做vue项目时,收集的一些有意思的功能

    1. element-ui dialog组件添加可拖拽位置 可拖拽宽高 https://segmentfault.com/a/1190000012940145

  2. GITHUB下载ANDRIOD源码

    1 git clone https://android.googlesource.com/device/common.git 2 git clone https://android.googlesou ...

  3. LightOJ - 1067 - Combinations(组合数)

    链接: https://vjudge.net/problem/LightOJ-1067 题意: Given n different objects, you want to take k of the ...

  4. centos6.5下安装docker的过程办法

    转载:https://www.cnblogs.com/tymagic/p/10794477.html 在看了网上N多复制粘贴的文章,又尝试无效后,我把我最终成功的办法发出来,希望能帮到拼命干环境的你. ...

  5. (13)打鸡儿教你Vue.js

    一小时复习 vue.js是一个JavaScriptmvvm库,是以数据驱动和组件化的思想构建的,相比angular.js,vue.js提供了更加简洁,更加容易理解的api,如果习惯了jquery操作d ...

  6. Xilinx ISE的时序约束

    使用Synplify Pro加时序约束.综合完毕后,可以在ISE中进行布局.布线.需要用.ucf文件指定布局布线的时钟约束.前者可以比后者小. 早期的ISE,两个约束可以继承.现在用的高版本,反而需要 ...

  7. Nginx 所使用的 epoll 模型是什么?

    对于 Nginx,相信有过 Web 服务部署经验的同学都不陌生,它有以下特点: 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 相较于 A ...

  8. setTimeout 的理解

    setTimeout,延迟一段时间执行代码. setTimeout(func,0),这代码的作用并不是简单地和直接调用func一个效果: 1:动态往DOM树中插入元素,然后立刻操作这个元素(选择文本框 ...

  9. Android中Popupwindow和Dialog的区别

    Android中的对话框有两种:PopupWindow和AlertDialog.它们都可以实现弹窗功能,但是他们之间有一些差别,下面总结了一点. (1)Popupwindow在显示之前一定要设置宽高, ...

  10. Perl快速查找素数

    查找N内的所有素数,首先想到的就是: 对整数N从2开始到sqrt(N),进行整除计算,能整除则计算N+1,然后循环.方法简单,但效率低下.1000,000内的素数个数: #!/usr/bin/perl ...