1. 图的基本操作–图的深度优先和广度优先遍历
# include <stdio.h>
# include <stdlib.h>
# define max_vertex_num 100
typedef char VertexData;
typedef int AdjType;
typedef int OtherInfo;
int visisted[ max_vertex_num] = { 0 } ;
int visisted1[ max_vertex_num] = { 0 } ;
typedef struct Node
{
int adjvex;
struct Node * nextarc;
} Node;
typedef struct VVertexNode
{
char data;
Node * firstarc;
} VertexNode[ max_vertex_num] ;
typedef struct
{
VertexNode vertex;
int vexnum, arcnum;
} AdjList;
int LocateVertex ( AdjList * G, VertexData v)
{
int j = - 1 , k;
for ( k = 0 ; k < G-> vexnum; k++ )
{
if ( G-> vertex[ k] . data == v) return k;
}
return ( j) ;
}
void CreateList ( AdjList * G)
{
int i;
char v1, v2;
printf ( "用邻接表来创建图\n请输入图的顶点个数和弧数\n" ) ;
scanf ( "%d%d" , & G-> vexnum, & G-> arcnum) ;
printf ( "请用一行输入图的各个顶点,不用逗号隔开\n" ) ;
getchar ( ) ;
for ( i = 0 ; i < G-> vexnum; i++ )
{
scanf ( "%c" , & G-> vertex[ i] . data) ;
G-> vertex[ i] . firstarc = NULL ;
}
printf ( "请用一行输入图中所有两顶点之间的弧,例如,a,b b,c b,d\n" ) ;
int a1, a2;
for ( i = 0 ; i < G-> arcnum; i++ )
{
getchar ( ) ;
scanf ( "%c,%c" , & v1, & v2) ;
a1 = LocateVertex ( G, v1) ;
a2 = LocateVertex ( G, v2) ;
if ( a1 == - 1 || a2 == - 1 ) return ;
Node* p1 = ( Node* ) malloc ( sizeof ( Node) ) ;
p1-> adjvex = a2;
p1-> nextarc = G-> vertex[ a1] . firstarc;
G-> vertex[ a1] . firstarc = p1;
Node* p2 = ( Node* ) malloc ( sizeof ( Node) ) ;
p2-> adjvex = a1;
p2-> nextarc = G-> vertex[ a2] . firstarc;
G-> vertex[ a2] . firstarc = p2;
}
}
void print ( AdjList * G)
{
int i;
printf ( "打印出用邻接表创建的无向图\n" ) ;
for ( i = 0 ; i < G-> vexnum; i++ )
{
printf ( "%c---->" , G-> vertex[ i] . data) ;
Node * t;
t = G-> vertex[ i] . firstarc;
while ( t != NULL )
{
printf ( " %c " , G-> vertex[ t-> adjvex] . data) ;
t = t-> nextarc;
}
printf ( "\n" ) ;
}
}
void DFS ( AdjList * g, int i)
{
Node * t;
printf ( "%c" , g-> vertex[ i] . data) ;
visisted[ i] = 1 ;
t = g-> vertex[ i] . firstarc;
while ( t)
{
int w = t-> adjvex;
if ( ! visisted[ w] )
DFS ( g, w) ;
t = t-> nextarc;
}
}
void BFS ( AdjList * g, int i)
{
int q[ max_vertex_num] ;
int front = 0 , rear = 0 ;
printf ( "%c" , g-> vertex[ i] . data) ;
visisted1[ i] = 1 ;
q[ rear++ ] = i;
Node * p;
while ( rear > front)
{
int temp = q[ front++ ] ;
p = g-> vertex[ temp] . firstarc;
while ( p != NULL )
{
int neighbor = p-> adjvex;
if ( ! visisted1[ neighbor] )
{
printf ( "%c" , g-> vertex[ neighbor] . data) ;
visisted1[ neighbor] = 1 ;
q[ rear++ ] = neighbor;
}
p = p-> nextarc;
}
}
}
int main ( )
{
AdjList GG;
CreateList ( & GG) ;
print ( & GG) ;
printf ( "以A开始的深度优先遍历(DFS):\n" ) ;
DFS ( & GG, 0 ) ;
printf ( "\n以A开始的广度优先遍历(BFS):\n" ) ;
BFS ( & GG, 0 ) ;
printf ( "\n" ) ;
return 0 ;
}
2. 图的基本操作–基于邻接矩阵建立图
# include <stdio.h>
# include <stdlib.h>
# define MAX_VERTEX_NUM 100
# define OK 1
# define ERROR - 1
typedef char VertexData;
typedef int AdjType;
typedef int OtherInfo;
typedef struct
{
AdjType adj;
OtherInfo info;
} ArcNode;
typedef struct
{
VertexData vertex[ MAX_VERTEX_NUM] ;
ArcNode arcs[ MAX_VERTEX_NUM] [ MAX_VERTEX_NUM] ;
int vexnum, arcnum;
} AdjMatrix;
int LocateVertex ( AdjMatrix * G, VertexData v)
{
for ( int k = 0 ; k < G-> vexnum; k++ )
{
if ( G-> vertex[ k] == v) return k;
}
return - 1 ;
}
void CreateMatrix ( AdjMatrix * G)
{
int i, j, k;
char v1, v2;
printf ( "用邻接矩阵来创建图\n请输入图的顶点个数和弧数\n" ) ;
scanf ( "%d%d" , & G-> vexnum, & G-> arcnum) ;
for ( i = 0 ; i < G-> vexnum; i++ )
{
for ( j = 0 ; j < G-> vexnum; j++ )
{
G-> arcs[ i] [ j] . adj = 0 ;
}
}
printf ( "请用一行输入图的各个顶点,不用逗号隔开\n" ) ;
getchar ( ) ;
for ( i = 0 ; i < G-> vexnum; i++ )
{
scanf ( "%c" , & G-> vertex[ i] ) ;
}
printf ( "请用一行输入图中所有两顶点之间的弧,例如,a,b b,c b,d\n" ) ;
for ( k = 0 ; k < G-> arcnum; k++ )
{
getchar ( ) ;
scanf ( "%c,%c" , & v1, & v2) ;
int a1 = LocateVertex ( G, v1) ;
int a2 = LocateVertex ( G, v2) ;
if ( a1 == - 1 || a2 == - 1 )
{
printf ( "顶点不存在.\n" ) ;
return ;
}
G-> arcs[ a1] [ a2] . adj = 1 ;
G-> arcs[ a2] [ a1] . adj = 1 ;
}
}
void PrintMatrix ( AdjMatrix * G)
{
printf ( "打印出用邻接矩阵创建的无向图\n" ) ;
for ( int i = 0 ; i < G-> vexnum; i++ )
{
for ( int j = 0 ; j < G-> vexnum; j++ )
{
printf ( "%d " , G-> arcs[ i] [ j] . adj) ;
}
printf ( "\n" ) ;
}
}
int main ( )
{
AdjMatrix G;
CreateMatrix ( & G) ;
PrintMatrix ( & G) ;
return 0 ;
}
3. 图的基本操作–基于邻接表建立图
# include <stdio.h>
# include <stdlib.h>
# define max_vertex_num 100
typedef char VertexData;
typedef struct Node
{
int adjvex;
struct Node * nextarc;
} Node;
typedef struct
{
VertexData data;
Node * firstarc;
} VertexNode;
typedef struct
{
VertexNode vertex[ max_vertex_num] ;
int vexnum, arcnum;
} AdjList;
int LocateVertex ( AdjList * G, VertexData v)
{
for ( int k = 0 ; k < G-> vexnum; k++ ) {
if ( G-> vertex[ k] . data == v) return k;
}
return - 1 ;
}
void CreateList ( AdjList * G)
{
int i;
char v1, v2;
printf ( "用邻接表来创建图\n请输入图的顶点个数和弧数\n" ) ;
scanf ( "%d%d" , & G-> vexnum, & G-> arcnum) ;
printf ( "请用一行输入图的各个顶点,不用逗号隔开\n" ) ;
getchar ( ) ;
for ( i = 0 ; i < G-> vexnum; i++ )
{
scanf ( "%c" , & G-> vertex[ i] . data) ;
G-> vertex[ i] . firstarc = NULL ;
}
printf ( "请用一行输入图中所有两顶点之间的弧,例如,a,b b,c b,d\n" ) ;
for ( i = 0 ; i < G-> arcnum; i++ )
{
getchar ( ) ;
scanf ( "%c,%c" , & v1, & v2) ;
int a1 = LocateVertex ( G, v1) ;
int a2 = LocateVertex ( G, v2) ;
if ( a1 == - 1 || a2 == - 1 )
{
printf ( "顶点未找到\n" ) ;
return ;
}
Node * p1 = ( Node * ) malloc ( sizeof ( Node) ) ;
p1-> adjvex = a2;
p1-> nextarc = G-> vertex[ a1] . firstarc;
G-> vertex[ a1] . firstarc = p1;
Node * p2 = ( Node * ) malloc ( sizeof ( Node) ) ;
p2-> adjvex = a1;
p2-> nextarc = G-> vertex[ a2] . firstarc;
G-> vertex[ a2] . firstarc = p2;
}
}
void print ( AdjList * G)
{
printf ( "打印出用邻接表创建的无向图\n" ) ;
for ( int i = 0 ; i < G-> vexnum; i++ )
{
printf ( "%c---->" , G-> vertex[ i] . data) ;
Node * t = G-> vertex[ i] . firstarc;
while ( t != NULL )
{
printf ( " %c " , G-> vertex[ t-> adjvex] . data) ;
t = t-> nextarc;
}
printf ( "\n" ) ;
}
}
int main ( )
{
AdjList GG;
CreateList ( & GG) ;
print ( & GG) ;
return 0 ;
}
4. 社交网络下的谣言传播分析(1)
# include <stdio.h>
# include <stdlib.h>
# define MAX_VERTEX_NUM 20
typedef struct ArcNode {
int adjvex;
struct ArcNode * nextarc;
int info;
} ArcNode;
typedef struct VNode {
int data;
ArcNode * firstarc;
} VNode, AdjList[ MAX_VERTEX_NUM] ;
typedef struct ALGraph {
AdjList vertices;
int vexnum, arcnum;
} ALGraph;
void CreateUDN ( ALGraph * G) {
scanf ( "%d %d" , & G-> vexnum, & G-> arcnum) ;
for ( int i = 1 ; i <= G-> vexnum; i++ ) {
G-> vertices[ i] . data = i;
G-> vertices[ i] . firstarc = NULL ;
}
for ( int i = 0 ; i < G-> arcnum; i++ ) {
int a1, a2, w;
scanf ( "%d %d %d" , & a1, & a2, & w) ;
ArcNode * p1 = ( ArcNode* ) malloc ( sizeof ( ArcNode) ) ;
p1-> adjvex = a2;
p1-> info = w;
p1-> nextarc = G-> vertices[ a1] . firstarc;
G-> vertices[ a1] . firstarc = p1;
ArcNode * p2 = ( ArcNode* ) malloc ( sizeof ( ArcNode) ) ;
p2-> adjvex = a1;
p2-> info = w;
p2-> nextarc = G-> vertices[ a2] . firstarc;
G-> vertices[ a2] . firstarc = p2;
}
}
int VexCount ( ALGraph G, int v)
{
int sum = 0 ;
ArcNode * p = G. vertices[ v] . firstarc;
while ( p != NULL )
{
sum += p-> info;
p = p-> nextarc;
}
return sum;
}
int main ( )
{
ALGraph G;
CreateUDN ( & G) ;
for ( int i = 0 ; i < G. vexnum; i++ )
{
printf ( "%d " , VexCount ( G, i + 1 ) ) ;
}
printf ( "\n" ) ;
return 0 ;
}
5. 求最小生成树的权值之和
# include <stdio.h>
# include <stdlib.h>
# define MAX_VERTEX_NUM 100
# define INFINITY 99999
typedef struct {
int u, v;
int weight;
} Edge;
typedef struct {
int vexnum;
int edgenum;
Edge edges[ MAX_VERTEX_NUM * ( MAX_VERTEX_NUM - 1 ) / 2 ] ;
} Graph;
int parent[ MAX_VERTEX_NUM] ;
int find ( int x) {
if ( parent[ x] != x) {
parent[ x] = find ( parent[ x] ) ;
}
return parent[ x] ;
}
void unionSet ( int x, int y) {
int rootX = find ( x) ;
int rootY = find ( y) ;
if ( rootX != rootY) {
parent[ rootX] = rootY;
}
}
int compareEdges ( const void * a, const void * b) {
return ( ( Edge * ) a) -> weight - ( ( Edge * ) b) -> weight;
}
int kruskalMST ( Graph * G)
{
int totalWeight = 0 , i;
int edgeCount = 0 ;
for ( i = 1 ; i <= G-> vexnum; i++ ) {
parent[ i] = i;
}
qsort ( G-> edges, G-> edgenum, sizeof ( Edge) , compareEdges) ;
for ( i = 0 ; i < G-> edgenum; i++ ) {
int u = G-> edges[ i] . u;
int v = G-> edges[ i] . v;
int weight = G-> edges[ i] . weight;
if ( find ( u) != find ( v) )
{
unionSet ( u, v) ;
totalWeight += weight;
edgeCount++ ;
if ( edgeCount == G-> vexnum - 1 )
{
break ;
}
}
}
return totalWeight;
}
int main ( )
{
Graph G;
int n, count, i;
scanf ( "%d %d" , & n, & count) ;
G. vexnum = n;
G. edgenum = count;
for ( i = 0 ; i < count; i++ )
{
int u, v, weight;
scanf ( "%d %d %d" , & u, & v, & weight) ;
G. edges[ i] . u = u;
G. edges[ i] . v = v;
G. edges[ i] . weight = weight;
}
int result = kruskalMST ( & G) ;
printf ( "%d\n" , result) ;
return 0 ;
}
6. 动态规划模拟测试题
# include <stdio.h>
# include <limits.h>
# define VERTEX_NUM 12
# define MAX_EDGES 21
struct Edge {
int from, to, weight;
} ;
struct Edge edges[ MAX_EDGES] = {
{ 1 , 2 , 9 } , { 1 , 3 , 7 } , { 1 , 4 , 3 } , { 1 , 5 , 2 } ,
{ 2 , 6 , 4 } , { 2 , 7 , 2 } , { 2 , 8 , 1 } , { 3 , 6 , 2 } , { 3 , 7 , 7 } ,
{ 4 , 8 , 11 } , { 5 , 7 , 11 } , { 5 , 8 , 8 } , { 6 , 9 , 6 } , { 6 , 10 , 5 } ,
{ 7 , 9 , 4 } , { 7 , 10 , 3 } , { 8 , 10 , 5 } , { 8 , 11 , 6 } , { 9 , 12 , 4 } ,
{ 10 , 12 , 2 } , { 11 , 12 , 5 }
} ;
int main ( ) {
int stages;
scanf ( "%d" , & stages) ;
int stage_nodes[ stages] [ VERTEX_NUM] ;
int stage_sizes[ stages] ;
for ( int i = 0 ; i < stages; ++ i) {
int node;
stage_sizes[ i] = 0 ;
while ( scanf ( "%d" , & node) == 1 ) {
stage_nodes[ i] [ stage_sizes[ i] ++ ] = node;
if ( getchar ( ) == '\n' ) break ;
}
}
int dist[ VERTEX_NUM + 1 ] ;
int path[ VERTEX_NUM + 1 ] ;
for ( int i = 0 ; i <= VERTEX_NUM; ++ i) {
dist[ i] = INT_MAX;
path[ i] = - 1 ;
}
dist[ 1 ] = 0 ;
for ( int i = 0 ; i < stages - 1 ; ++ i) {
for ( int j = 0 ; j < stage_sizes[ i] ; ++ j) {
int u = stage_nodes[ i] [ j] ;
for ( int k = 0 ; k < MAX_EDGES; ++ k) {
if ( edges[ k] . from == u) {
int v = edges[ k] . to;
if ( dist[ u] != INT_MAX && dist[ u] + edges[ k] . weight < dist[ v] ) {
dist[ v] = dist[ u] + edges[ k] . weight;
path[ v] = u;
}
}
}
}
}
int target = 12 ;
printf ( "%d\n" , dist[ target] ) ;
int shortest_path[ VERTEX_NUM] ;
int shortest_path_length = 0 ;
for ( int v = target; v != - 1 ; v = path[ v] ) {
shortest_path[ shortest_path_length++ ] = v;
}
for ( int i = shortest_path_length - 1 ; i >= 0 ; -- i) {
printf ( "%d " , shortest_path[ i] ) ;
}
printf ( "\n" ) ;
return 0 ;
}