
深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接结点。总结起来可以这样说:每次都在访问完当前结点后首先访问当前结点的第一个邻接结点。
访问图中的一个点之后,一次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发,依次访问它们的邻接点,并且使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问。所以广度遍历要用队列来完成。
Kruskal算法在找最小生成树结点之前,需要对权重从小到大进行排序。将排序好的权重边依次加入到最小生成树中,(如果加入时产生回路就跳过这条边,加入下一条边)。当所有的结点都加入到最小生成树中后,就找到了这个连通图的最小生成树。
算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
1.找到一个没有后继的顶点;2.从图中删除这个顶点,在列表中插入顶点的标记。 然后重复1和2,直到所有顶点都从图中删除,这时候列表显示的顶点顺序就是拓扑排序的结果了,有向图就不能使用拓扑排序。
建图,宾客的关系放到图中。
对visited[][]进行初始化为0
若friends[a][b]==1,则为朋友关系,直接输出“No problem”
定义一个变量flag=0;
将vitited中相应宾客的值置为1;
对宾客a,b进行VIS函数调用,类似于图的深度遍历
对a,b检查是否存在共同的朋友
存在,flag=1
不存在,则flag=0;
if(宾客是敌人关系){
存在共同朋友,输出"OK but..."
否则输出“No way”
}
else(不是朋友也不是敌人){
存在共同朋友,输出"No problem"
否则输出“OK”
}


一开始不小心将函数中(i==y)便返回写成了(i==x),导致falg的返回值错误,既只对了(friends[a][b]==1)直接输出的部分,朋友的朋友的情况判断错误。
先建图和对visited[]初始化为0
从顶点v=1开始对图进行广度遍历
将v进队列
while(队列不为空){
  将number置为队列头元素,删除队列头元素;
         遍历顶点i=0 to  i<N{
     若visited[i]==0且G[number][i]==1;
              将i进队,visited[i]置为1,记录节点数,同时记录i的数值
                        }
}
   若访问到该层的最后一个节点
        层数加一,改变这一层访问的最后一个节点 
    层数达到6便结束,返回记录的节点数


忘记将进队的i的visited[i]置为1,导致节点数错误。格式错误是没把分子乘1.0,没能保留小数点后两位。
给G[][]和lowcost[]数组赋初值;
找出N-1个顶点  i=1 to i=N{
在(V-U)中找出离U中最近的顶点
      用k记录最近顶点的编号
  累加顶点间最短路径的数值
  给lowcost[k]赋值-1,标记k已经加入U
         for j=1 to j=N
              修改lowcost[]中的值
            }
    判断输入数据是否以保证畅通  
         不能则返回-1
             否则返回最短路径的总和sum


这道题是用最小生成树中Prim()算法计算的,书中有类似代码,但一直写一直是部分正确,怎么改都是,去网上查了下代码,思路基本也一样,然后提交网上的代码就全对了,而自己的还不知道哪错了,然后根据网上对的代码一直改自己代码中认为错误的地方,在PTA上反复提交,找了半小时才发现是因为我给G[][]的赋的初值太小了,网上是999999,虽然知道错在哪里了,但还是一脸懵逼,为什么G[][]=999999能全对。。。。。。

#ifndef __GRAPH_H__
#define __GRAPH_H__
typedef struct graph *Graph;
Graph graph_create(int n);
void graph_destroy(Graph);
void graph_add_edge(Graph, int source, int sink);
int graph_vertex_count(Graph);
int graph_edge_count(Graph);
int graph_out_degree(Graph, int source);
int graph_has_edge(Graph, int source, int sink);
void graph_foreach(Graph g, int source,
    void (*f)(Graph g, int source, int sink, void *data),
    void *data);
#endif
/* basic directed graph type */
/* the implementation uses adjacency lists
 * represented as variable-length arrays */
/* these arrays may or may not be sorted: if one gets long enough
/* and you call graph_has_edge on its source, it will be */
struct graph {
   int n;                                                                              /* number of vertices */
   int m;                                                                              /* number of edges */
   struct successors {
          int d;                                                                       /* number of successors */
          int len;                                                                  /* number of slots in array */
          char is_sorted;                                                        /* true if list is already sorted */
          int list[1];                                                           
                                                                                          /* actual list of successors */
   } *alist[1];
};
/* create a new graph with n vertices labeled 0..n-1 and no edges */
Graph
graph_create(int n)
{
   Graph g;
   int i;
   g = malloc(sizeof(struct graph) + sizeof(struct successors *) * (n-1));
   assert(g);
   g->n = n;
   g->m = 0;
   for(i = 0; i < n; i++) {
          g->alist[i] = malloc(sizeof(struct successors));
          assert(g->alist[i]);
          g->alist[i]->d = 0;
          g->alist[i]->len = 1;
          g->alist[i]->is_sorted= 1;
   }
   return g;
}
/* free all space used by graph */
void
graph_destroy(Graph g)
{
   int i;
   for(i = 0; i < g->n; i++) free(g->alist[i]);
   free(g);
}
/* add an edge to an existing graph */
void
graph_add_edge(Graph g, int u, int v)
{
   assert(u >= 0);
   assert(u < g->n);
   assert(v >= 0);
   assert(v < g->n);
   /* do we need to grow the list? */
   while(g->alist[u]->d >= g->alist[u]->len) {
          g->alist[u]->len *= 2;
          g->alist[u] =
                 realloc(g->alist[u], 
                        sizeof(struct successors) + sizeof(int) * (g->alist[u]->len - 1));
   }
   /* now add the new sink */
   g->alist[u]->list[g->alist[u]->d++] = v;
   g->alist[u]->is_sorted = 0;
   /* bump edge count */
   g->m++;
}
/* return the number of vertices in the graph */
int
graph_vertex_count(Graph g)
{
   return g->n;
}
/* return the number of vertices in the graph */
int
graph_edge_count(Graph g)
{
   return g->m;
}
/* return the out-degree of a vertex */
int
graph_out_degree(Graph g, int source)
{
   assert(source >= 0);
   assert(source < g->n);
   return g->alist[source]->d;
}
/* when we are willing to call bsearch */
#define BSEARCH_THRESHOLD (10)
static int
intcmp(const void *a, const void *b)
{
   return *((const int *) a) - *((const int *) b);
}
/* return 1 if edge (source, sink) exists), 0 otherwise */
int
graph_has_edge(Graph g, int source, int sink)
{
   int i;
   assert(source >= 0);
   assert(source < g->n);
   assert(sink >= 0);
   assert(sink < g->n);
   if(graph_out_degree(g, source) >= BSEARCH_THRESHOLD) {
          /* make sure it is sorted */
          if(! g->alist[source]->is_sorted) {
                 qsort(g->alist[source]->list,
                               g->alist[source]->d,
                               sizeof(int),
                               intcmp);
          }             
          /* call bsearch to do binary search for us */
          return 
                 bsearch(&sink,
                               g->alist[source]->list,
                               g->alist[source]->d,
                               sizeof(int),
                               intcmp)
                 != 0;
   } else {
          /* just do a simple linear search */
          /* we could call lfind for this, but why bother? */
          for(i = 0; i < g->alist[source]->d; i++) {
                 if(g->alist[source]->list[i] == sink) return 1;
          }
          /* else */
          return 0;
   }
}
/* invoke f on all edges (u,v) with source u */
/* supplying data as final parameter to f */
void
graph_foreach(Graph g, int source,
   void (*f)(Graph g, int source, int sink, void *data),
   void *data)
{
   int i;
   assert(source >= 0);
   assert(source < g->n);
   for(i = 0; i < g->alist[source]->d; i++) {
          f(g, source, g->alist[source]->list[i], data);
   }
}这段代码有动态分配的数组来存放邻接节点,这是一份PineWiki网站里面提供的一份图的表示的代码,实现的很优美吧?动态分配数组,长度可以扩展,既不浪费空间,又不会带来性能损失,它告诉我们鱼和熊掌也是可以兼得的。

原文:https://www.cnblogs.com/peng075078/p/9178537.html