大虾虽然是个贼,但也是一个血性男儿。越想越是兴奋,并想当一回义贼,窃富济贫!他把这种理念深深地在心中扎下了根,一时兴起,于是乎拿下昨天的战国列强图,单手托着脸在那里若有如无的思考。网上找了单元最短路径的资料,得出三个臭皮匠:
单终点最短路径:找出从每个定点到指定终点的最短路径(反向思考便是单源最短路径问题啦),就如很多国家都以赶超美国为目标。
单对顶点最短路径:找出两个指定点的最短路径(找到起始点的单源即可),就如中国若赶超美国,必先要超过日本、德国等等。
每对顶点的最短路径:顾名思义啦,这个更容易了,我们首先要认清与各个国家之间的差异。
假设我们与下面的国家的关系用权重表示,权重越大,代表关系越紧密,即路径越短。大虾这个贼又查了大部分为2010~2011年的资料,经济是基础,由于朝鲜基本上闭关锁国,独自强大,基本可以忽略不计了,具体见下表:
由此根据战国列国图,并将上述数据除以100,得出下图,大虾一想,现在应该是经济列国时代。
#include <stdio.h>
#include <stdlib.h>
#define BIG 65535 //65535无穷大,大虾修改为0
#define NUM 6
//Dijkstra算法函数,求给定顶 点到其余各点的最短路径
//参数:邻接矩阵、顶点数、出发点的下标、结果数组、路径前一点记录
void Dijkstra(int Cost[][NUM],int n,int v0,int Distance[],int prev[])
{
int s[NUM];
int mindis,dis;
int i,j,u;
//初始化
for(i=0;i<n;i++)
{
Distance[i]=Cost[v0][i];
s[i]=0;
if(Distance[i]==BIG)
prev[i] = -1;
else
prev[i] = v0;
}
Distance[v0] = 0;
s[v0] =1; //标记v0
//在当前还未找到最短路径的顶点中,
//寻找具有最短距离的顶点
for(i=1;i<n;i++)
{//每循环一次,求得一个最短路径
mindis=0;
u = v0;
for (j=0;j<n;j++) //求离出发点最近的顶点
//if(s[j]==0&&Distance[j]<mindis)
if(s[j]==0&&Distance[j]>mindis) //大虾修改为大于
{
mindis=Distance [j];
u=j;
} // if语句体结束,j循环结束
s[u] = 1;
for(j=0;j<n;j++) //修改递增路径序列(集合)
//if(s[j]==0&&Cost[u][j]<BIG)
if(s[j]==0&&Cost[u][j]<BIG)
{ //对还未求得最短路径的顶点
//求出由最近的顶点 直达各顶点的距离
dis=Distance[u] +Cost[u][j];
// 如果新的路径更短,就替换掉原路径
printf("[bean] %d\n", dis);
//if(Distance[j]>dis)
if(Distance[j]<dis)
{
Distance[j] = dis;
prev[j] = u;
}
} // if 语句体结束,j循环结束
} // i循环结束
}
// 输出最短路径
// 参数:路径前一点记录、出发点的下标、到达点下标、顶点数
void PrintPrev(char **v, int prev[],int v0,int vn,int n)
{
int tmp = vn;
int i = 1, j, ii;
//临时存路径
int *tmpprv = (int *)malloc(n*sizeof(int));
//初始化数组
for(ii=0;ii<n;ii++)
tmpprv[ii] = 0;
//记录到达点下标
tmpprv[0] = vn+1;
//中间点用循环记录
for(j=1;j<n;j++)
{
if(prev[tmp] != -1&&tmp != 0)
{
tmpprv[i] = prev[tmp]+1;
tmp = prev[tmp];
i++;
}
else break;
}
//输出路径,数组逆向输出
for(i=n-1;i>=0;i--)
{
if(tmpprv[i] !=0)
{ //排除0元素
tmp = tmpprv[i];
printf("\t%s",v[tmp-1]);
if(i) //不是最后一个输出符号
printf(" --> ");
}
}
}
//主函数
int main()
{
//给出有向网的顶点数组
char *Vertex[NUM]={"CHN","JPN","KOR","RUS","IND","USA"};
//给出有向网的邻接矩阵
int Cost[NUM][NUM]={{0,28,20,6,6,36},
{28,0,36,2,1,26},
{20,36,0,1,1,12},
{6,2,1,0,1,4},
{6,1,1,1,0,8},
{36,26,12,4,8,0},
};
int Distance[NUM]; //存放求得的最短路径长度
int prev[NUM]; //存放求得的最短路径
//调用Dijkstra算法函数,求顶点V1到其余各点的最短路径
//参数:邻接矩阵、顶点数、出发点的下标、 结果数组
int i;
Dijkstra(Cost,NUM,0,Distance,prev);
for(i=0;i<NUM;i++)
{
//输出最短路径长度
printf("%s-->%s\t%d", Vertex[0], Vertex[i],Distance[i]);
//输出最短路径
PrintPrev(Vertex,prev,0,i,NUM);
printf("\n");
}
return 0;
}
得出的结果如下:
根据上面的结果,精心分析得出下面关系图:
大虾瞅了瞅上面的图,主要就是中美日韩,当然这只是个大概,不可忽视的还有个欧盟。暂且不考虑,,从上面的路径关系来看该注意与韩国这个邻邦连横了。虽然想到这,但是今天新闻实在是让大虾按耐不住,美禁中国籍科学家参加NASA学术会议。大虾还是跳了起来,翻箱倒底,把前面的偷窃之物(注意大虾是窃富济贫的哦)合计了一下,离自己的目标还是很远,于是乎决定再来一次大的,然后支持中国举办航天会议,而且一更开放的态度诚邀国内外的科学家们,对,就是在此时似乎更应该举办一届这样展示中华胸怀的会议。心情澎湃的大虾,拍桌而起,下定决心。突然一阵警笛,一下惊醒,目前大虾还需多多风头,话说大虾为啥有这样的本事,要说起当年被父母丢弃在峨眉山脚的经历,更多精彩请看下集。