解题思路:Dijkstra算法
1、给城镇编号
2、转换成图
3、用Dijkstra算法求解
#include <stdio.h> #include <string.h> #include <malloc.h> #define MaxVex 200 #define INF 0x3f3f3f3f int G[MaxVex][MaxVex]; int visit[MaxVex]= {0}; int path[MaxVex]; int cnt[MaxVex]; int num[MaxVex]= {0}; int sum[MaxVex]= {0}; int tmp[MaxVex]= {0}; char s[MaxVex][4]; int Nv,Ne; int start,destination; int getNum(char *c) { int i; for(i=0; i<Nv; i++) { if(!strcmp(s[i],c)) return i; } } void Init() { char c1[4]; char c2[4]; scanf("%d %d %s %s",&Nv,&Ne,c1,c2); int i; for(i=0; i<Nv-1; i++) { scanf("%s%d",s[i],&sum[i]); tmp[i]=sum[i]; } strcpy(s[Nv-1],c1); start=getNum(c1); destination=getNum(c2); memset(G,INF,sizeof(G)); int v1,v2,x; for(i=0; i<Ne; i++) { scanf("%s %s %d",c1,c2,&x); v1=getNum(c1); v2=getNum(c2); G[v1][v2]=x; G[v2][v1]=G[v1][v2]; } for(i=0; i<Nv; i++) { if(G[start][i]!=INF) cnt[i]=1;//start->i存在边,则初始化路径数为1 } } void Dijkstra(int start) { visit[start]=1; num[start]=1; int i,j,w; for(i=0; i<Nv; i++) { int MIN=INF; for(j=0; j<Nv; j++) { if(!visit[j]&&G[start][j]<MIN) { MIN=G[start][j]; w=j; } } visit[w]=1; for(j=0; j<Nv; j++) { if(!visit[j]&&MIN+G[w][j]<G[start][j]) { //路径较短 G[start][j]=MIN+G[w][j];//更新路径长度 cnt[j]=cnt[w];//统计路径数 path[j]=w;//记录上一个节点编号 sum[j]=sum[w]+tmp[j];//更新杀敌数 num[j]=num[w]+1;//统计节点数 } else if(!visit[j]&&MIN+G[w][j]==G[start][j]) { //路径长度一致 cnt[j]=cnt[w]+cnt[j];//统计路径数 if(num[w]+1>num[j]) { //经过节点较多 num[j]=num[w]+1;//统计节点数 path[j]=w;//记录上一个节点编号 sum[j]=sum[w]+tmp[j];//更新杀敌数 } else if(num[w]+1==num[j]) { //节点一样 if(sum[w]>sum[path[j]]) { //杀敌人数较多 path[j]=w;//记录上一个节点编号 sum[j]=sum[w]+tmp[j];//更新杀敌数 } } } } } } int main() { Init(); int i; for(i=0; i<Nv; i++) { path[i]=start; } Dijkstra(start); int road[MaxVex]= {0}; int t=0,r=destination; while(r!=start) { road[t++]=r; r=path[r]; } road[t]=start; for(i=t; i>=0; i--) { printf("%s",s[road[i]]); if(i!=0) printf("->"); } printf(" "); printf("%d %d %d",cnt[destination],G[start][destination],sum[destination]); return 0; }