题目
图是一种使用广泛的数据结构。本次实验要求设计有向带权图的抽象数据类型,实现图的构造、顶点的增删查,边的增删改、深度优先遍历与广度优先遍历、单源最短路径、多源最短路径、判断图中是否存在负环。
效果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXX 10000
#define INF 0x3fffffff
int g_1[MAXX][MAXX],g_2[MAXX][MAXX];
char point[MAXX];
int n;//n个节点,编号最大的
char v[MAXX];
int dist[MAXX];
void add_g_1(int b,int c,int d){
point[b]=1;
point[c]=1;
g_1[b][c]=d;
if(b > n) n=b;
if(c > n) n=c;
}
void g1tog2(){
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
if(g_1[i][j]<INF){
g_2[i][j]=g_1[i][j];
g_2[j][i]=g_1[i][j];
}
}
}
}
void dfs(int x){
v[x]=1;
printf("%d ",x);
for(int i=0;i<=n;i++){
if(v[i]==0 && g_2[x][i]!=INF){
dfs(i);
}
}
}
void bfs(int x){
int q[MAXX];
int p=0,o=0;
q[o++]=x;
v[x]=1;
while(p<o){
x=q[p++];
printf("%d ",x);
for(int i=0;i<=n;i++){
if(v[i]==0 && g_2[x][i]!=INF){
q[o++]=i;
v[i]=1;
}
}
}
}
void Dijkstra(int x){
dist[x]=0;
while(1)
{
int min=INF;
int y=-1;
for(int i=0;i<=n;i++)
{
if(dist[i]<min && v[i]==0)
{
min=dist[i];
y=i;
}
}
if(y==-1) return;
v[y]=1;
for(int j=0;j<=n;j++){
if(v[j]==0 && dist[y]+g_1[y][j]<dist[j]){
dist[j]=dist[y]+g_1[y][j];
}
}
}
}
int bf(int x){
for(int i=0;i<=n;i++){
dist[i]=INF;
}
memset(v,0,sizeof(v));
dist[x]=0;
int flag;
for (int i = 0; i <= n; i++) {
flag=0;
for (int j = 0; j <= n; j++) {
for (int k = 0; k <= n; k++) {
if (dist[k] > dist[j] + g_1[j][k]) {
dist[k] = dist[j] + g_1[j][k];
flag = 1;
}
}
}
if (!flag) return 1;
}
flag = 0;
for (int j = 0; j <= n; j++) {
for (int k = 0; k <= n; k++) {
if (dist[k] > dist[j] + g_1[j][k]) {
flag = 1;
}
}
}
return !flag;
}
int main()
{
memset(point,0,sizeof(point));
for(int i=0;i<MAXX;i++){
for(int j=0;j<MAXX;j++){
g_1[i][j]=INF;
g_2[i][j]=INF;
}
}
int now=0;//当前操作指令
while(1){
printf("请输入需求\r\n");
printf(" 0 输入节点\r\n");
printf(" 1 节点\r\n");
printf(" 2 边\r\n");
printf(" 3 无向图dfs\r\n");
printf(" 4 无向图bfs\r\n");
printf(" 5 单源最短路\r\n");
printf(" 6 任意两点最短路\r\n");
printf(" 7 判断负环\r\n");
scanf("%d",&now);
if(now==0){
int a,b,c,d;
scanf("%d %d",&n,&a);
n-=1;
for(int i=0;i<a;i++){
scanf("%d %d %d",&b,&c,&d);
add_g_1(b,c,d);
}
}else if(now==1){
printf(" 1增加 2删除 3查找\r\n");
int a,b,c,d;
scanf("%d",&a);
if(a==1){
scanf("%d",&b);
point[b]=1;
}else if(a==2){
scanf("%d",&b);
point[b]=0;
if(b==n){
n--;
}
}else if(a==3){
scanf("%d",&b);
if(point[b]==1){
printf(" 存再\r\n");
}else{
printf(" 不存再\r\n");
}
}
}else if(now==2){
printf(" 1增加 2删除 3改变\r\n");
int a,b,c,d;
if(a==1 || a==3){
scanf("%d %d %d",&b,&c,&d);
add_g_1(b,c,d);
}else if(a==2){
scanf("%d %d" ,&b,&c);
g_1[b][c]=INF;
}
}else if(now==3){
int a;
g1tog2();
scanf("%d",&a);
memset(v,0,sizeof(v));
dfs(a);
printf("\r\n");
}else if(now==4){
g1tog2();
int a;
scanf("%d",&a);
memset(v,0,sizeof(v));
bfs(a);
printf("\r\n");
}else if(now==5){
for(int i=0;i<=n;i++){
dist[i]=INF;
}
memset(v,0,sizeof(v));
int a;
scanf("%d",&a);
Dijkstra(a);
for(int j=0;j<=n;j++){
if(j==a)continue;
if(dist[j]==INF){
printf(" %d->%d:error ",a,j);
}else{
printf(" %d->%d:%d ",a,j,dist[j]);
}
}
}else if(now==6){
for(int i=0;i<=n;i++){
for(int i=0;i<=n;i++){
dist[i]=INF;
}
memset(v,0,sizeof(v));
Dijkstra(i);
for(int j=0;j<=n;j++){
if(j==i)continue;
if(dist[j]==INF){
printf("%d->%d:error ",i,j);
}else{
printf("%d->%d:%d ",i,j,dist[j]);
}
}
printf("\r\n");
}
}else if(now==7){
int fl=1;
for(int i=0;i<=n;i++){
if(bf(i)==0){
fl=0;
break;
}
}
if(fl){
printf("不存在负环\r\n");
}else{
printf("存在负环\r\n");
}
}else break;
}
return 0;
}