合縱連橫系列之曲線的救國

          大蝦雖然是個賊,但也是一個血性男兒。越想越是興奮,並想當一回義賊,竊富濟貧!他把這種理念深深地在心中紮下了根,一時興起,於是乎拿下昨天的戰國列強圖,單手託着臉在那裏若有如無的思考。網上找了單元最短路徑的資料,得出三個臭皮匠:

單終點最短路徑:找出從每個定點到指定終點的最短路徑(反向思考便是單源最短路徑問題啦),就如很多國家都以趕超美國爲目標。

單對頂點最短路徑:找出兩個指定點的最短路徑(找到起始點的單源即可),就如中國若趕超美國,必先要超過日本、德國等等。

每對頂點的最短路徑:顧名思義啦,這個更容易了,我們首先要認清與各個國家之間的差異。

假設我們與下面的國家的關係用權重表示,權重越大,代表關係越緊密,即路徑越短。大蝦這個賊又查了大部分爲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學術會議。大蝦還是跳了起來,翻箱倒底,把前面的偷竊之物(注意大蝦是竊富濟貧的哦)合計了一下,離自己的目標還是很遠,於是乎決定再來一次大的,然後支持中國舉辦航天會議,而且一更開放的態度誠邀國內外的科學家們,對,就是在此時似乎更應該舉辦一屆這樣展示中華胸懷的會議。心情澎湃的大蝦,拍桌而起,下定決心。突然一陣警笛,一下驚醒,目前大蝦還需多多風頭,話說大蝦爲啥有這樣的本事,要說起當年被父母丟棄在峨眉山腳的經歷,更多精彩請看下集。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章