SDUST数据结构 - chap7 图
判断题:
选择题:
函数题:
6-1 邻接矩阵存储图的深度优先遍历:
裁判测试程序样例:
#include <stdio.h> typedef enum {false, true} bool;
#define MaxVertexNum 10 /* 最大顶点数设为10 */
#define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex; /* 用顶点下标表示顶点,为整型 */
typedef int WeightType; /* 边的权值设为整型 */ typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
bool Visited[MaxVertexNum]; /* 顶点的访问标记 */ MGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */ void Visit( Vertex V )
{
printf(" %d", V);
} void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) ); int main()
{
MGraph G;
Vertex V; G = CreateGraph();
scanf("%d", &V);
printf("DFS from %d:", V);
DFS(G, V, Visit); return 0;
} /* 你的代码将被嵌在这里 */
代码:
void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) )
{
Visit(V);
Visited[V] = true;
for(int i=0;i<Graph->Nv;i++)
{
if((Graph->G[V][i]==1)&&(!Visited[i]))//1代表相通,Visited非1代表没有访问过
DFS(Graph, i, Visit);//递归
}
}
6-2 邻接表存储图的广度优先遍历:
裁判测试程序样例:
#include <stdio.h> typedef enum {false, true} bool;
#define MaxVertexNum 10 /* 最大顶点数设为10 */
typedef int Vertex; /* 用顶点下标表示顶点,为整型 */ /* 邻接点的定义 */
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex AdjV; /* 邻接点下标 */
PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */
}; /* 顶点表头结点的定义 */
typedef struct Vnode{
PtrToAdjVNode FirstEdge; /* 边表头指针 */
} AdjList[MaxVertexNum]; /* AdjList是邻接表类型 */ /* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
AdjList G; /* 邻接表 */
};
typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */ bool Visited[MaxVertexNum]; /* 顶点的访问标记 */ LGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */ void Visit( Vertex V )
{
printf(" %d", V);
} void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ); int main()
{
LGraph G;
Vertex S; G = CreateGraph();
scanf("%d", &S);
printf("BFS from %d:", S);
BFS(G, S, Visit); return 0;
} /* 你的代码将被嵌在这里 */
代码:
void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) )
{
Vertex v[11];//利用一个数组队列存储遍历的节点
PtrToAdjVNode ptg;
int i=0;
int j=0;
v[j++]=S;
Visited[S] = true;//标记为已遍历
while(i<j)
{
Vertex vv = v[i++];
Visit(vv);//输出首位
ptg = Graph->G[vv].FirstEdge;//指向输出的队首的指针
while(ptg)//将输出的队首的未遍历的子节点入队
{
if(!Visited[ptg->AdjV])
{
v[j++] = ptg->AdjV;
Visited[ptg->AdjV] = true;
}
ptg = ptg->Next;
}
}
}
7-1 畅通工程之局部最小花费问题:
输入样例:
4
1 2 1 1
1 3 4 0
1 4 1 1
2 3 3 0
2 4 2 1
3 4 5 0
输出样例:
3
代码:
#include<stdio.h>
int main()
{
int dist[105],cost[105][105],visit[105]={0};
int i,j;
int n,m,sum=0;
scanf("%d", &n);
for(i=1;i<=n;i++){//每个点赋初值
for(j=1;j<=n;j++){
cost[i][j]=cost[j][i]=99999;
}
}
m = n*(n-1)/2;
int a,b,chengben,zhuangtai;
while(m--)
{
scanf("%d%d%d%d", &a, &b, &chengben, &zhuangtai);
if(zhuangtai == 0)
cost[a][b] = cost[b][a] = chengben;
else
cost[a][b] = cost[b][a] = 0;
}
for(j=1;j<=n;j++)//编号从1开始
dist[j] = cost[1][j];
visit[1] = 1;
dist[1] = 0;
for(i=1;i<n;i++)
{
int min=99999;
int flag=-1;
for(j=1;j<=n;j++)//以1号城镇为起点,找到距离1号城镇最近的城
{
if(visit[j]==0 && dist[j]<min)
{
min = dist[j];
flag=j;
}
}
visit[flag]=1;
if(flag!=-1)
{
sum+=dist[flag];//jiang成本算入
for(j=1;j<=n;j++)//已经找到距离1最近的k点,再以k为起点
{
if(visit[j]==0 && dist[j]>cost[flag][j])
dist[j] = cost[flag][j];
}
}
}
printf("%d\n",sum);
return 0;
}
7-2 畅通工程之最低成本建设问题:
输入样例1:
6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3
输出样例1:
12
输入样例2:
5 4
1 2 1
2 3 2
3 1 3
4 5 4
输出样例2:
Impossible
代码:
#include<stdio.h>
int main()
{
int n,m,sum=0;
int arr[1005][1005];
scanf("%d%d",&n,&m);
int dist[1001]={999999};// dist[i] 表示i节点到已有生成树的最短距离
for(int i=1;i<=n;i++)//初始化矩阵,每个点为 ∞
for(int j=1;j<=m;j++)
arr[i][j]=999999;
int x,y,z;
int flag=1;
for(int i=0;i<m;i++)//生成邻接矩阵
{
scanf("%d%d%d",&x,&y,&z);
arr[x][y] = arr[y][x] = z;
}
for(int i=1;i<=n;i++)//记录每个点到1的最短距离
dist[i] = arr[1][i];
dist[1] = 0;// 访问过的点设为0
while(1)
{
int a=0;
for(int i=1;i<=n;i++)
{
if(dist[i]<dist[a] && dist[i])
a = i;
}
if(!a)
break;
sum += dist[a];
dist[a] = 0;
for(int i=1;i<=n;i++)
{
if(arr[a][i] < dist[i])
dist[i] = arr[a][i];
}
}
for(int i=1;i<=n;i++)
{
if(dist[i])
flag=0;
}
if(!flag)
printf("Impossible\n");
else
printf("%d\n",sum);
return 0;
}
7-3 城市间紧急救援:
输入样例:
4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2
输出样例:
2 60
0 1 3
代码:
#include <stdio.h>
#include <string.h>
#define INF 999999
int n, m, s, d, vis[505], l[505][505], dis[505], p[505], sum[505], ans[505];
void dfs(int length, int people, int dd)
{
int i;
if(dd == s)
return;
for(i = 0 ; i < n ; i++)
{
if(length - l[dd][i] == dis[i] && people - p[dd] == sum[i])
{
dfs(dis[i], sum[i], i);
printf("%d ", i);
break;
}
}
}
void dij()
{
int i, j, k, min;
vis[s] = 1;
sum[s] = p[s];
ans[s] = 1;
for(i = 0 ; i < n ; i++)
{
dis[i] = l[s][i];
if(s != i && l[s][i] != INF)
{
sum[i] = p[i] + p[s];
ans[i] = 1;//
}
}
for(i = 0 ; i < n-1 ; i++)
{
min = INF;
for(j = 0 ; j < n ; j++)
{
if(!vis[j] && min > dis[j])
{
min = dis[j];
k = j;
}
}
vis[k] = 1;
for(j = 0 ; j < n; j++)
{
if(!vis[j])
{
if(dis[j] > dis[k] + l[k][j])
{
dis[j] = dis[k] + l[k][j];
sum[j] = sum[k] + p[j];
ans[j] = ans[k];//
}
else if(dis[j] == dis[k] + l[k][j])
{
ans[j] += ans[k];//
if(sum[j] < sum[k] + p[j])
{
sum[j] = sum[k] + p[j];
}
}
}
}
}
}
int main()
{
int i, j, x, y, ll;
scanf("%d %d %d %d", &n, &m, &s, &d);
for(i = 0 ; i < n ; i++)
for(j = 0 ; j < n ; j++)
{
l[i][j] = INF;
}
for(i = 0 ; i < n; i++)
{
scanf("%d", &p[i]);
}
for(i = 0 ; i < m ; i++)
{
scanf("%d %d %d", &x, &y, &ll);
l[x][y] = l[y][x] = ll;
}
if(n == 1)
{
printf("1 %d\n1", p[0]);
return 0;
}
dij();
printf("%d %d\n", ans[d], sum[d]);
printf("%d ", s);
dfs(dis[d], sum[d], d);
printf("%d", d);
return 0;
}
7-4 天梯地图:
输入样例1:
10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
5 4 0 2 3
5 9 1 1 4
0 6 0 1 1
7 3 1 1 2
8 3 1 1 2
2 5 0 2 2
2 1 1 1 1
1 5 0 1 3
1 4 0 1 1
9 7 1 1 3
3 1 0 2 5
6 3 1 2 1
5 3
输出样例1:
Time = 6: 5 => 4 => 8 => 3
Distance = 3: 5 => 1 => 3
输入样例2:
7 9
0 4 1 1 1
1 6 1 3 1
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 3 1
3 2 1 2 1
4 5 0 2 2
6 5 1 2 1
3 5
输出样例2:
Time = 3; Distance = 4: 3 => 2 => 5
代码:
#include<stdio.h>
#include<iostream>
using namespace std;
int sum[521];//记录找最短时间时到原点的距离
struct
{
int length;
int time;
}Graph[521][521];//建立地图
struct
{
int visit;
int length;
int pre;
}LVisit[521];//建立距离、访问表
struct
{
int visit;
int time;
int pre;
}TVisit[521];//建立时间、访问表
void InitGraph(int N, int M)//创建并初始化地图
{
for(int i=0; i<=N; i++)//初始化各点间的距离和时间均为无穷大
for(int j=0; j<=N; j++){
sum[j] = 0;
Graph[i][j].length = 9999999;
Graph[i][j].time = 9999999;
}
int v1, v2, way, length, time;
for(int i=0; i<M; i++){//读取输入创建地图
cin>>v1>>v2>>way>>length>>time;
Graph[v1][v2].length = length;
Graph[v1][v2].time = time;
if(way == 0){//非单行线,两地可互通
Graph[v2][v1].length = length;
Graph[v2][v1].time = time;
}
}
}
void InitVisit(int N, int S)// 初始化时间、距离、访问表
{
for(int i=0; i<=N; i++){
LVisit[i].visit = 0;//初始化为未访问
LVisit[i].length = Graph[S][i].length;//根据地图初始化到原点距离
TVisit[i].visit = 0;//初始化为未访问
TVisit[i].time = Graph[S][i].time;//根据地图初始化时间
if(TVisit[i].time!=9999999){//如果和原点相通设置前驱点为原点,并设置个时间点到原点距离
LVisit[i].pre = S;
TVisit[i].pre = S;
sum[i] = Graph[S][i].length;
}
}
LVisit[S].visit = 1;//设置原点已访问
TVisit[S].visit = 1;//设置原点已访问
}
void DST_L(int N, int S)//斯特拉求最短距离
{
for(int j=1; j<N; j++){
int mlpoint = N;//设置N点为最近点,N点已设为无穷远
for(int i=0; i<N; i++){
if(LVisit[i].length<LVisit[mlpoint].length&&!LVisit[i].visit)
mlpoint = i;
}//求出最近点并设置为已访问
LVisit[mlpoint].visit = 1;
for(int i=0; i<N; i++){//更新距离
if(!LVisit[i].visit){
//更新为更短的距离
if(LVisit[i].length>LVisit[mlpoint].length+Graph[mlpoint][i].length){
LVisit[i].length = LVisit[mlpoint].length+Graph[mlpoint][i].length;
LVisit[i].pre = mlpoint;//设置前驱点
}
//距离相同则节点少为优
else if(LVisit[i].length==LVisit[mlpoint].length+Graph[mlpoint][i].length){
int l1=0,l2=0;
int pre = LVisit[i].pre;
while(pre!=S){
l1++;
pre = LVisit[pre].pre;
}
pre = mlpoint;
while(pre!=S){
l2++;
pre = LVisit[pre].pre;
}
if(l1>l2)//节点多则更新
LVisit[i].pre = mlpoint;
}
}
}
} }
void DST_T(int N, int S)//斯特拉求最短时间
{
for(int j=1; j<N; j++){
int mtpoint = N;//无穷为最短点
for(int i=0; i<N; i++){
if(TVisit[i].time<TVisit[mtpoint].time&&!TVisit[i].visit)
mtpoint = i;
}//求出最短点并设置为已访问
TVisit[mtpoint].visit = 1;
for(int i=0; i<N; i++){
if(!TVisit[i].visit){
//更新最短时间
if(TVisit[i].time>TVisit[mtpoint].time+Graph[mtpoint][i].time){
TVisit[i].time = TVisit[mtpoint].time+Graph[mtpoint][i].time;
TVisit[i].pre = mtpoint;
sum[i] = sum[mtpoint] + Graph[mtpoint][i].length;//更新最短时间的距离
}//时间相同则根据距离更新,距离短的优先
else if(TVisit[i].time==TVisit[mtpoint].time+Graph[mtpoint][i].time){
if(sum[i]>sum[mtpoint]+Graph[mtpoint][i].length){//选距离更短的
TVisit[i].pre = mtpoint;
sum[i] = sum[mtpoint] + Graph[mtpoint][i].length;//更新其距离
}
}
}
}
}
}
int main()
{
int N, M;
cin>>N>>M;
InitGraph(N,M);//初始化并读取输入创建图
int S, D;
cin>>S>>D;
InitVisit(N, S);//创建并初始化距离、时间、访问表
DST_L(N,S);//求最短距离
DST_T(N,S);//求最短时间
int lpath[521];//最短距离路径表
int tpath[521];//最短时间路径表
int l=520, t=520;;
int pre = D;
while(pre!=S){//根据目的地不断往后后移,直到后移到原点
lpath[l]=pre;
pre = LVisit[pre].pre;
l--;
}
pre = D;
while(pre!=S){
tpath[t] = pre;
pre = TVisit[pre].pre;
t--;
}
if(t==l){//路径长度一样
int flag = 0;
for(int i=t+1; i<521; i++){//判断路径是否完全相同
if(tpath[i]!=lpath[i])
flag = 1;//不相等
}
if(flag == 1){//路径不同
cout<<"Time = "<<TVisit[D].time<<": "<<S;
for(int i = t+1; i<521; i++){
cout<<" => "<<tpath[i];
}
cout<<endl; cout<<"Distance = "<<LVisit[D].length<<": "<<S;
for(int i = l+1; i<521; i++){
cout<<" => "<<lpath[i];
}
}
else{//路径相同
cout<<"Time = "<<TVisit[D].time<<"; "<<"Distance = "<<LVisit[D].length<<": "<<S;
for(int i = t+1; i<521; i++){
cout<<" => "<<tpath[i];
}
}
return 0;
}
//路径不同
cout<<"Time = "<<TVisit[D].time<<": "<<S;
for(int i = t+1; i<521; i++){
cout<<" => "<<tpath[i];
}
cout<<endl; cout<<"Distance = "<<LVisit[D].length<<": "<<S;
for(int i = l+1; i<521; i++){
cout<<" => "<<lpath[i];
} }
7-5 关键活动:
输入样例:
7 8
1 2 4
1 3 3
2 4 5
3 4 3
4 5 1
4 6 6
5 7 5
6 7 2
输出样例:
17
1->2
2->4
4->6
6->7
代码:
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 10000
typedef struct Node {
int El;
int La;
}Nodes; int main() {
int n, m;
scanf("%d %d", &n, &m);
int DEEP[101] = { 0 }; //保存点的度数
int sort[101] = { 0 }; //保存排序结果
int a[101][101] = { 0 }; //保存路径长度
int end[101];
int b[101][101]; //保存关键路径
int sunxu[101]; //保存顺序
Nodes *N = (Nodes *)malloc(sizeof(Nodes)*(n+1));
for (int i = 1; i <= n; i++)
{ end[i] = -1;
N[i].El = 0;
N[i].La = MaxSize;
for (int j = 1; j <= n; j++)
{
a[i][j] = -1;
b[i][j] = -1;
}
}
int qi, zhong, chang, count = 0, px = 0, countt = 1;
for (int j = 1; j <= m; j++)
{
px = 0;
scanf("%d %d %d", &qi, &zhong, &chang);
a[qi][zhong] = chang;
DEEP[zhong]++;
for (int y = 1; y < j; y++)
{
if (zhong == sunxu[y]) {
px = 1;
break;
}
}
if (px != 1) {
sunxu[countt] = zhong;
countt ++ ;
}
}
int ss = 1, flag = 0,isend=1,QQ=1;
for (int i = 1; i <= n; i++)
{
int z=1,isend=1;
for (z = 1; z<=n; z++)
{
if (a[i][z] != -1) { isend = 0; break; } //不是结束点
}
if (isend == 1) {
end[count] = i;
count++;
}
flag = -1;
for (int j = 1; j <= n; j++)
{
if (DEEP[j] == 0) {
flag = 0;
DEEP[j] = -1;
sort[ss] = j;
ss++;
for (int k = 1; k <= n; k++)
{
if (a[j][k] != -1) {
DEEP[k]--;
}
}
break;
}
}
if (flag == -1) {
break;
}
}
if (flag == 0) {
int max = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (a[j][sort[i]] != -1) {
if (N[sort[i]].El < N[j].El + a[j][sort[i]]) {
N[sort[i]].El = a[j][sort[i]] + N[j].El;
}
}
}
}
for (int i = 1; i <= n; i++)
{
if (N[i].El > max) {
max = N[i].El;
}
}
printf("%d\n", max); int lengths = 0;
for (int z = 0; z < count; z++)
{
N[end[z]].La = max;
}
for (int l = n; l>=1; l--)
{
for (int i = 1; i <=n; i++)
{
if (a[i][sort[l]]!=-1) {
if (N[sort[l]].La - a[i][sort[l]] < N[i].La) {
N[i].La = N[sort[l]].La - a[i][sort[l]];
}
}
}
for (int x = 1; x <=n; x++)
{
if (a[x][sort[l]] != -1) {
if (N[sort[l]].La - a[x][sort[l]] == N[x].La&&N[x].La== N[x].El) {
b[x][sort[l]] = 1;
lengths++;
}
}
}
}
for (int p = 1; p <= n; p++) {
for (int k = countt - 1; k >= 1; k--) {
if (b[p][sunxu[k]] == 1) {
printf("%d->%d", p, sunxu[k]);
lengths--;
printf("\n");
}
}
}
}
else {
printf("0");
}
return 0;
}
SDUST数据结构 - chap7 图的更多相关文章
- python数据结构之图的实现
python数据结构之图的实现,官方有一篇文章介绍,http://www.python.org/doc/essays/graphs.html 下面简要的介绍下: 比如有这么一张图: A -> B ...
- hdu 1233:还是畅通工程(数据结构,图,最小生成树,普里姆(Prim)算法)
还是畅通工程 Time Limit : 4000/2000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submis ...
- 利用python+graphviz绘制数据结构关系图和指定目录下头文件包含关系图
作为一名linux系统下的C语言开发,日常工作中经常遇到两个问题: 一是分析代码过程中,各种数据结构互相关联,只通过代码很难理清系统中所有结构体的整体架构,影响代码消化的效率; 二是多层头文件嵌套包含 ...
- python数据结构之图的实现方法
python数据结构之图的实现方法 本文实例讲述了python数据结构之图的实现方法.分享给大家供大家参考.具体如下: 下面简要的介绍下: 比如有这么一张图: A -> B A ...
- python数据结构之图深度优先和广度优先实例详解
本文实例讲述了python数据结构之图深度优先和广度优先用法.分享给大家供大家参考.具体如下: 首先有一个概念:回溯 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到 ...
- 数据结构之图 Part2 - 1
邻接矩阵 网上很少有C# 写图的数据结构的例子,实际的项目中也从来没用过Array 这坨东西,随手写个,勿喷. namespace LH.GraphConsole { public struct Gr ...
- 数据结构之图 Part1
Part 1 预计使用7天的时间来过掉图相关的数据结构.第一天主要是一天图的基本概念,熟练掌握定义是一切交流和沟通的基础. 1定义 1.1图 有穷非空顶点,外加边. G(V,E) Graph Vert ...
- C++数据结构之图
图的实现是一件很麻烦的事情,很多同学可能在学数据结构时只是理解了图的基本操作和遍历原理,但并没有动手实践过.在此,我说说我的实现过程. 首先,在草稿纸上画一个图表,这里是有向图,无向图也一样,如下: ...
- 数据结构之--图(Graphics)
1.1:图的定义和术语 图是一种比线性表和树更为复杂的数据结构.在线性表中,数据元素之间仅有线性关系,每个元素仅有一个直接前驱和一个直接后继:在树形结构中,数据元素之间有着明显的层次关系,并且每一 ...
随机推荐
- Oracle数据泵常用命令
导读:expdp和impdp是oracle数据库之间移动数据的工具,本文简单总结了数据泵的常用命令,希望对大家有帮助. 前言 expdp和impdp是oracle数据库之间移动数据的工具.expd ...
- 2020.12.16 模拟赛x+1
A. 接力比赛 跑两遍背包,再进行一些玄学的剪枝 代码 #include<cstdio> #include<algorithm> #define rg register inl ...
- 多年总结IDEA 使用技巧 (建议收藏!)
很长一段时间没有更新了,前段时间转测试了,浪费了一些时间,终于可以写文章了,今天来写一下之前自己开发的一些习惯,因为自己本身自己是一个极简主义所以 开发喜欢这样:. 全屏显示 我们可以使用[Prese ...
- draggable()拖拽时限制移动区域
jQuery-UI为我们提供了一个非常便捷的拖拽方法:draggable(),在使用此方法时,我们可能会希望控件只在某一区域中移动,不能被拖出边界,这样的话我们可以使用下面的方法: 调用draggab ...
- HCIP -- OSPF 总结
OSPF:Open Shortest path First :开方式最短路径优先 一.基础知识: 1.使用范围:IGP 2.协议算法特点:链路状态型路由协议,SPF算法 3.协议是否传递网络掩码:是 ...
- Win10-1909删除自带的微软输入法,添加美式键盘
删除自带 输入法切换
- Blogs添加横幅滚动条
#1.定义CSS样式 .box { width: 100%; margin: 0 auto; /* border: 0.2px solid gray; */ overflow: hidden; } . ...
- (五)cp命令复制文件或者目录
一.cp的含义.功能及命令格式 cp(英文copy的缩写)命令可以将一个文件或者目录从一个位置复制到另外一个位置.cp的功能就是将一个文件复制成 一个指定的目的文件或者复制到一个指定的目录中,兼具复制 ...
- Error:java: JDK isn't specified for module 'xxx'异常的解决方法
问题描述 博主启动的项目的时候出现了一个这样的异常 解决方法 打开左上角这个Project Structure
- (java)五大常用算法
算法一:分治法 基本概念 1.把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并. 2.分治策略是对于一个 ...