C语言图的运算

一、实验目的

  1. 掌握图的逻辑结构和物理结构,能根据实验内容分析问题,选择合适的数据结构描述问题,并定义物理结构,尤其是构造有向网;
  2. 学会灵活运用图描述工程问题;
  3. 掌握关键路径和最短路径的求解原理、实现方法;
  4. 学会灵活运用拓扑排序解决关键路径求解过程中的问题;
  5. 学会使用Dijkstra算法或Floyd算法求顶点间最短路径;
  6. 从终端输入AOE网相关信息,具体的输入和输出格式不限;
  7. 算法要具有较好的健壮性,对错误操作要做适当处理。

二、实验任务

  1. 对给出的一个具体工程,输入相关数据,构造一个AOE网;
  2. 求出该项工程的所有关键活动,通过关键活动所对应的从源点到汇点的路径求出关键路径;
  3. 对给出的一个具体的有向网或无向网,输入相关数据,构造邻接矩阵;
  4. 求出该网络每对顶点间的最短路径。

三、实验过程与结果

1.

#include"stdafx.h"
#include <iostream>
#include <iomanip>
#include "stdlib.h"
#include<stdio.h>
#include<string.h>
using namespace std;
////////////////////////////Stack
typedef int ElemType;
typedef struct{ElemType *base;int top;int stacksize;}Sqstack;
bool stackIsEmtype(Sqstack S){if(!S.top)return 1;else return 0;}
bool InitSqstack(Sqstack &S,int stacksize){
	S.base=(ElemType*)malloc(stacksize*sizeof(ElemType));
	if(!S.top)return 0;else{S.stacksize=stacksize;S.top=0;return 1;}}
bool Push(Sqstack &S,ElemType e){	
	ElemType *newbase; 
	if(S.top==S.stacksize){
		newbase=(ElemType*)realloc(S.base,(S.stacksize+1)*sizeof(ElemType));
		if(!newbase)
			return 0;
		S.base=newbase;
		S.stacksize++;
	}
	S.base[S.top]=e;S.top++;return 1;}
bool Pop(Sqstack &S,ElemType &e){
	if(!S.top)return 0;else{S.top--;e=S.base[S.top];return 1;}}
////////////////////////////Queue
typedef int QElemtype;
typedef struct{QElemtype *base;int front,rear;int queueSize;}CirQueue;
bool InitCirQueue(CirQueue &Q,int Qsize){
	Q.base=new QElemtype[Qsize];
	if(!Q.base)return 0;
	Q.queueSize=Qsize;Q.front=Q.rear=0;return 1;}
bool queueIsEmpty(CirQueue Q){if(Q.front==Q.rear)return 1;else return 0;}
bool insertQueue(CirQueue &Q,QElemtype e){
	if((Q.rear+1)%Q.queueSize==Q.front)return 0;
	Q.base[Q.rear]=e;Q.rear=(Q.rear+1)%Q.queueSize;return 1;}
bool deleteQueue(CirQueue &Q,QElemtype &e){
	if(Q.front==Q.rear)return 0;
	e=Q.base[Q.front];Q.front=(Q.front+1)%Q.queueSize;return 1;}
////////////////////////////Graph
#define MAX 40
typedef char VertexType[20]; 
typedef enum{DG,DN,UDG,UDN}GraphKind;
typedef struct ArcNode{int adjvex;int weight;struct ArcNode *nextarc;}ArcNode;
typedef struct VNode{VertexType data;ArcNode *firstarc;}VNode;
typedef struct{VNode vertices[MAX];int vexNum,arcNum;GraphKind kind;}ALGraph;
typedef struct VexTimeType{int ve;int vl;}VexTime;
int locateVex(ALGraph &G,VertexType v){
	int i;
	for(i=0;i<G.vexNum;i++)if(strcmp(G.vertices[i].data,v)==0)return i;
	return -1;
}
void createGraph(ALGraph &G){
	VertexType v1,v2;int d;
	int i,j,k;
	ArcNode *p;
	FILE *f;
    char fn[100];
	
	G.kind=DN;
    cout<<"please input source file name:";cin>>fn;
    //可输入测试文件名distG13.txt
	f=fopen(fn,"r");
    fscanf(f,"%d%d",&G.vexNum,&G.arcNum);
	cout<<G.vexNum<<"  "<<G.arcNum<<endl;
    for(i=0;i<G.vexNum;++i)
		{fscanf(f,"%s",G.vertices[i].data);G.vertices[i].firstarc=NULL;}	
    for (i=0;i<G.vexNum;i++) cout<<G.vertices[i].data<<" ";cout<<endl;
   
	for(k=0;k<G.arcNum;++k){
		fscanf(f,"%s%s%d",v1,v2,&d);
		cout<<v1<<"-->"<<v2<<":"<<d<<endl;
		if((i=locateVex(G,v1))==-1)return ;
		if((j=locateVex(G,v2))==-1)return ;
		p=new ArcNode;p->weight=d;
		p->adjvex=j;
		p->nextarc=G.vertices[i].firstarc;
		G.vertices[i].firstarc=p;}
	fclose(f);
}
void findIndegree(ALGraph &G,int indegree[]){
	int i;
	ArcNode *p;
	for(i=0;i<G.vexNum;i++)indegree[i]=0;
	for(i=0;i<G.vexNum;i++)
	{p=G.vertices[i].firstarc;
	 while(p){indegree[p->adjvex]++;p=p->nextarc;}}}
bool ve_time(ALGraph &G,VexTime vtime[],Sqstack &S){
	int i,k;
	int count=0;
	int *indegree;
	ArcNode *p;
	CirQueue Q;
	InitCirQueue(Q,G.vexNum);
	indegree=new int[G.vexNum];
	for(i=0;i<G.vexNum;i++)vtime[i].ve=0;
	findIndegree(G,indegree);
	for(i=0;i<G.vexNum;i++){if(indegree[i]==0)insertQueue(Q,i);}
	while(!queueIsEmpty(Q)){
		deleteQueue(Q,i);Push(S,i);count++;
		p=G.vertices[i].firstarc;
		while(p){
			k=p->adjvex;indegree[k]--;
			if(indegree[k]==0)insertQueue(Q,k);
			if(vtime[i].ve+p->weight>vtime[k].ve)
				vtime[k].ve=vtime[i].ve+p->weight;
			p=p->nextarc;} }
	if(count<G.vexNum)return 0;else return 1;
}
void vl_time(ALGraph &G,VexTime vtime[],Sqstack &S){
	int i,k;ArcNode *p;
	Pop(S,k);
	for(i=0;i<G.vexNum;i++)vtime[i].vl=vtime[k].ve;
	while(!stackIsEmtype(S)){
		Pop(S,i);p=G.vertices[i].firstarc;
		while(p){
			k=p->adjvex;
			if(vtime[k].vl-p->weight<vtime[i].vl)
				vtime[i].vl=vtime[k].vl-p->weight;
			p=p->nextarc;}  }
}
bool criticalpath(ALGraph &G){
	int i,k,al,ae;
	VexTime *vtime;
	ArcNode *p;
	Sqstack S;
	InitSqstack(S,G.vexNum);
	vtime=new VexTime[G.vexNum];
	if(!ve_time(G,vtime,S))return 0;
	vl_time(G,vtime,S);
	cout<<"所求关键活动如下:"<<endl;
	for(i=0;i<G.vexNum;i++){
		p=G.vertices[i].firstarc;
		while(p)
		{k=p->adjvex;ae=vtime[i].ve;al=vtime[k].vl-(p->weight);
		 if(ae==al)
		  cout<<"<"<<G.vertices[i].data<<","<<G.vertices[k].data<<">:"<<p->weight<<endl;
		  //cout<<G.vertices[i].data<<"-->"<<G.vertices[k].data<<endl;
		 p=p->nextarc;}    }
	return 1;
}
int main(){ALGraph G;createGraph(G);criticalpath(G);return 0;}

2.

#include"stdafx.h"
#include<iostream> 
#include<iomanip>
using namespace std;
#define  MAX 100
#define  N    100
int a[MAX][MAX],path[MAX][MAX];     //全局矩阵
FILE *f1;

void pf(int c0,int c1)          //递归求最短路径存入文件
  { int T;
    T=path[c0][c1];
    if(T==0) fprintf(f1,"->V%d",c1);//cout<<"->"<<"V"<<c1;
    else{pf(c0,T);pf(T,c1);}
  }

void p(int c0,int c1)          //递归求最短路径
  { int T;
    T=path[c0][c1];
    if(T==0) cout<<"->"<<"V"<<c1;
    else{p(c0,T);p(T,c1);}
  }

void floyd(int cost[][MAX],int n)
  { int i,j,k;
    for(i=1;i<=n;i++)
      for(j=1;j<=n;j++){a[i][j]=cost[i][j];path[i][j]=0;}
    for(k=1;k<=n;k++)
     for(i=1;i<=n;i++)
      for(j=1;j<=n;j++)
       if(a[i][k]+a[k][j]<a[i][j]){a[i][j]=a[i][k]+a[k][j];path[i][j]=k;}
      cout<<"***********************"<<endl;
   }
 void print(int h[][MAX],int n)
 {int i,j;
  for(i=1;i<=n;i++)
    {cout<<endl;
     for(j=1;j<=n;j++) cout<<setw(6)<<h[i][j];
     cout<<endl;
    }
  cout<<endl;
 }

int main()
 { int c0,c1,i,j,k,n,cost[MAX][MAX];

   char fn[100];
   printf("please input n and cost:\n");  //输入结点数和cost矩阵
   scanf("%d\n",&n);
   for(i=1;i<=n;i++)
   for(j=1;j<=n;j++)
   scanf("%d",&cost[i][j]);
   print(cost,n);
   floyd(cost,n);
   print(a,n);print(path,n);
   cout<<"please input file name:";cin>>fn;
   f1=fopen(fn,"w");
    for(c0=1;c0<=n;c0++)
     for(c1=1;c1<=n;c1++)
       {fprintf(f1,"V%d",c0);
       //cout<<"V"<<c0;
        pf(c0,c1);
        //cout<<": "<<a[c0][c1]<<endl;
        fprintf(f1,": %ld\n",a[c0][c1]);}
   fclose(f1);
   k=1;
   while(k)   //查询键盘所输入顶点对间的最短路径及长度
   { printf("please input c0 and c1:\n");scanf("%d%d",&c0,&c1);
     if(c0>=1&&c0<=n&c1>=1&&c1<=n)
       {cout<<"V"<<c0;p(c0,c1);cout<<": "<<a[c0][c1]<<endl;}
     else if(c0==0&&c1==0)k=0;
   }
   return 0;
 }
posted @ 2026-01-06 21:48  东血  阅读(1)  评论(0)    收藏  举报

载入天数...载入时分秒...