#include <stdio.h>
#include <stdlib.h>
#include <stdafx.h>
#include <malloc.h>
#define INFINITY 9999 /*最大值∞*/
#define MAX_VEX_NUM 30 /*图的最大顶点数目*/
typedef struct{
int vexnum; /*图的当前顶点数目和弧(边)的数目*/
int adj[MAX_VEX_NUM][MAX_VEX_NUM]; /*邻接矩阵*/
}AdjGraph;
int createGraph(AdjGraph *G, int *start, int *end)/*读入数据,建立有向图*/
{
int n, m, i, j, k, s, count;
int temp[MAX_VEX_NUM];
printf("输入旅游景点数目和公交线路条数:\n");
scanf("%d %d",&n, &m);
if(n<=1||m<1) return -1;
printf("输入起始景点编号和终止景点编号:\n");
scanf("%d %d",start,end);
if(*start<0||*start>n-1||*end<0||*end>n-1) return -1;
G->vexnum=n;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
G->adj[i][j]=INFINITY; /*邻接矩阵初始化*/
for(s=0;s<m;s++)
{
printf("请输入第%d条公交线路途经各景点的编号:\n",s+1);
scanf("%d",&k);
count=0;
while(k!=-1)
{ temp[count++]=k; scanf("%d",&k); }
for(i=0;i<count-1;i++)
for(j=i+1;j<count;j++) /*当前线路中,从t[i]到t[j]有直达公交车*/
G->adj[temp[i]][temp[j]]=1;
}
return 0;
}
int findMinmum(AdjGraph G,int start,int end) /*找出并返回图中从顶点start到end的最短路径*/
/*长度(最少上车次数)*/
{
int s[MAX_VEX_NUM]; /*s[i]==1表示已求出到达景点i的最少上车次数*/
int i,j,u,*dist;
int min;
if(start==end) return 0;
dist=(int *)malloc(sizeof(int)); /*存储start到各景点的最少上车次数*/
for(i=0;i<G.vexnum;i++)
{
dist[i]=G.adj[start][i]; /*从start可直达的景点的上车次数置1*/
s[i]=0; /*所有景点i的最少上车次数还未找到*/
}
s[start]=1; /*已求出到达景点start的最少上车次数*/
dist[start]=0; /*从景点start到start的最少上车次数等于0*/
for(i=0;i<G.vexnum;i++)
{
min=INFINITY;
u=start;
for(j=0;j<G.vexnum;j++)
if(s[j]==0&&dist[j]<min)
{ min=dist[j]; u=j; } /*u是从start出发能够到达的所有景点中上车次数最少者*/
s[u]=1; /*已经找到从景点start到u的最少上车次数,将u加入集合s*/
for(j=0;j<G.vexnum;++j) /*更新当前情况下其他景点的最少上车次数*/
if(s[j]==0&&min+G.adj[u][j]<dist[j])
dist[j]=min+G.adj[u][j];
}
return dist[end]; /*返回从景点start到景点end的最少上车次数*/
}
int main()
{
int start,end,m,forshow;
AdjGraph G;
if(createGraph(&G,&start,&end)==-1)
{
printf("创建有向图失败!\n");
return -1;
}
m=findMinmum(G,start,end); /*求从start到end的最少上车次数*/
if(m==0)
printf("从景点%d到景点%d不需要乘车\n",start,end);
else if(m<INFINITY)
printf("从景点%d到景点%d的最少换车次数为:%d\n",start,end,m-1);
else
printf("无解!\n");
scanf("%d",&forshow);
return 0;
}