【432】COMP9024,Exercise9

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

原文地址:https://www.cnblogs.com/alex-bn-lee/p/11351524.html

时间: 2024-10-09 02:49:00

【432】COMP9024,Exercise9的相关文章

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

先说下遇到这个问题的背景吧. 就是在页面中有个div,这个div右上角(或者其他位置)有个 × 的图标(这个图标添加tooltip工具提示),光标移到这个图标时,触发tooltip,提示“点击移除”这样类似的字样,然后点击后,把这个div作remove()这样的删除操作. 然后,问题来了,因为这个div被remove()了,导致生成的tooltip对应的 × 图标也被remove(),因为找不到,所以对应的mouseout(可能是mouseleave事件,参考了一下bootstrap的源码,没找

点滴积累【C#】---验证码,ajax提交

效果: 思路: 借用ashx文件创建四位验证,首先生成四位随机数字.然后创建画布,再将创建好的验证码存入session,然后前台进行button按钮将文本框中的值进行ajax请求到后台,和session中的验证码进行对比,成功返回true,失败返回false. 代码: [前台] 1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="verifycodeDemo.aspx.cs"

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

本文主要讲解 集成 第三方社交账号登录 为什么会有这个需求? 主要是因为目前互联网的网站数量太多,如果在各个站点都注册一个账号 用户非常不容易记住每个账号的用户名和密码,并且非常难保证每个账号的密码足够安全 而目前流行的社交网站 基本上每个用户都有账号,如果通过这类社交网站登录 就能得到如下几点好处 用户不用再注册其他账号 用户只能维护社交账户足够安全就行了,使用此社交账号登录的就是安全的了 常见的第三方社交账号有哪些? QQ 微信 新浪微博 人人网 百度 Github 如何加入第三方登录功能?

【UIKit】UIAlert,UIActionSheet

[Alert] 1.加入协议 <UIAlertViewDelegate,UIActionSheetDelegate> 2. -(IBAction)btnShowAlertView:(id)sender { UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"标题" message:@"对话框的内容" delegate:self cancelButtonTitle:@"关闭" o

【专题】偏序,扫描线

[关键字]偏序,数点,树状数组,线段树,扫描线. 因为涉及多种算法,所以整合到一起. [扫描线] 二维数点,偏序 ★数点问题 ★关于偏序问题的一些总结 一维偏序:排序二分 树状数组 二维偏序:排序扫描线+树状数组(差分)/线段树 三维偏序:排序扫描线+cdq分治+树状数组 排序扫描线+二维数据结构 基本思想是一维扫描线顺序扫描维护差分,一维用数据结构维护区间(线段树维护区间,树状数组差分维护前缀和). [BZOJ3161]布娃娃(扫描线+线段树) BZOJ 4059 Cerc2012 Non-b

【序列化】小结,逐步完善中

网上查了资料,序列化有多种方法,这里我写上自己刚用过的一种生成XML文件的,有需要的朋友可以自己百度一下其他方法. 1.添加引用 "using System.Xml.Serialization;": 2.用"[Serializable]"标记上要序列化的类,如下图 [Serializable] public class LogService { public string strName; public string strImage; public string

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

[题解]Leyni,罗莉和队列(树状数组) HRBUST - 1356 将整个序列reverse一下,现在就变成了从高到低的排队.题目就变成了,定位一个妹子,问这个妹子前面的比这个妹子小的妹子中,下标最小的数是哪个. 所以以年龄为下标,以(原数组)下标为值建立一颗值域线段树,由于我们只要找到在原数组下标最小的哪一个,所以相当于动态维护前缀\(\min\) ,由于我们只要查询比当前定位妹子小的一段前缀,所以拿树状数组代替就是了. 由于这群妹子是神仙(年龄可达1e9),所以要离散化一下. 复杂度\(

【转】双层,多层vpn连接实现及分析

转载自:http://bbs.51cto.com/thread-1099702-1.html 相信很多人之前都看过一篇帖子<WJ是如何找到发帖人>,这篇帖子原来原出处safe121,由核总从乌云分享到自己的个人网站!假如没有看过看过的话,可以从这里去了解一下!<传送门>    也是因为这个帖子的缘由,我和论坛的 @问题好解决 决定做一些简单的实验去验证一下!我们想比较一下,多层vpn与多层跳板这个是否都能实现隐藏的作用!但在实验这期间有很多的失败,最终选择一个简单容易实现的方案去验

【python】-- 列表,元组

本节内容 字符串格式化输出 数据运算 for循环 while循环 列表 元组 [字符串格式化输出] 占位符 %s-string,%d-digital,%f -float # __author__:"ShengXin" #__date__:2017/8/23 name = input("name:") age = int(input("age:")) job = input("job:") salary = input(&quo