合纵连横系列之曲线的救国

          大虾虽然是个贼,但也是一个血性男儿。越想越是兴奋,并想当一回义贼,窃富济贫!他把这种理念深深地在心中扎下了根,一时兴起,于是乎拿下昨天的战国列强图,单手托着脸在那里若有如无的思考。网上找了单元最短路径的资料,得出三个臭皮匠:

单终点最短路径:找出从每个定点到指定终点的最短路径(反向思考便是单源最短路径问题啦),就如很多国家都以赶超美国为目标。

单对顶点最短路径:找出两个指定点的最短路径(找到起始点的单源即可),就如中国若赶超美国,必先要超过日本、德国等等。

每对顶点的最短路径:顾名思义啦,这个更容易了,我们首先要认清与各个国家之间的差异。

假设我们与下面的国家的关系用权重表示,权重越大,代表关系越紧密,即路径越短。大虾这个贼又查了大部分为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学术会议。大虾还是跳了起来,翻箱倒底,把前面的偷窃之物(注意大虾是窃富济贫的哦)合计了一下,离自己的目标还是很远,于是乎决定再来一次大的,然后支持中国举办航天会议,而且一更开放的态度诚邀国内外的科学家们,对,就是在此时似乎更应该举办一届这样展示中华胸怀的会议。心情澎湃的大虾,拍桌而起,下定决心。突然一阵警笛,一下惊醒,目前大虾还需多多风头,话说大虾为啥有这样的本事,要说起当年被父母丢弃在峨眉山脚的经历,更多精彩请看下集。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值