POJ 4083 我愛北大

這道題真的是目前爲止見過的最有情懷的題目之一,感覺做完以後就不再愛北大了…

1、因爲最後要求輸出任意兩個路徑之間的最短距離,因此我選擇使用的Floyd算法(數據比較弱,樣例代碼是貪心,應該也能過),Floyd算法用一個dis[N][N]數組存儲任意兩個點之間的距離,用path數組存儲路徑。

2、Floyd算法用的是動態規劃的思想,設置初始數組爲題目中所給的任意兩個地點之間的距離, 然後每次更新這個二維數組,更新的思路是每次打開一個點k,比較從i到j經過點k的路徑和不經過點k的路徑,即dis[i][j] 和dis[i][k]+dis[k][j]的大小,取比較小的那個只更新到dis[i][j]中,若經過k比較短,則要更新path路徑,把k存到path[i][j]中去,輸出的時候再按照順序找回去就可以了。

3、有個坑爹的地方在於連個地點之間的距離可能會出現多次,要取最短的存進去,然後圖是無向圖,因此存距離的時候dis[i][j]和dis[j][i]相等,查bug查了好久,果然還是剛接觸這種數據結構經驗不足。

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<limits.h>
using namespace std;

#define MAXP 33

string place[MAXP];
int dis[MAXP][MAXP]={0};
int path[MAXP][MAXP]={0};
int P,Q,R;

int getNum(string src){
    for(int i=0;i<P;++i){
        if(src==place[i]){
            return i;
        }
    }
    return -1;
}

void workP(){
    scanf("%d",&P);
    for(int i=0;i<P;++i){
        for(int j=0;j<P;++j){
            dis[i][j] = INT_MAX;
            path[i][j] = -1;
        }
    }
    for(int i=0;i<P;++i){
        cin>>place[i];
    }
    for(int i=0;i<P;++i){
        dis[i][i] = 0;
        path[i][i] = i;
    }
}

void debug(){
    for(int i=0;i<P;++i){
        for(int j=0;j<P;++j){
            if(dis[i][j]==INT_MAX)
                cout<<setw(4)<<"-1"<<' ';
            else
                cout<<setw(4)<<dis[i][j]<<' ';
        }
        cout<<endl;
    }
    cout<<endl;
}

void process(){
    for(int k=0;k<P;++k){
        for(int i = 0;i<P;++i){
            for(int j=0;j<P;++j){
                int dis1 = dis[i][j];
                int dis2 = INT_MAX;
                if(dis[i][k]!=INT_MAX && dis[k][j] != INT_MAX){
                    dis2 = dis[i][k]+dis[k][j];
                }
                if(dis2<dis1){
                    dis[i][j] = dis2;
                    path[i][j] = k;
                }
            }
        }
        //debug();
    }

}

void workQ(){
    scanf("%d",&Q);
    while(Q--){
        string p1,p2;
        int dis0;
        cin>>p1>>p2;
        scanf("%d",&dis0);
        int a = getNum(p1),b = getNum(p2);
        if(dis0<dis[a][b]){
            dis[a][b] = dis0;
            dis[b][a] = dis0;
        }
    }
    //debug();
    process();
}

void output(int _x,int _y){
    if (path[_x][_y] == -1){
        cout << "->(" << dis[_x][_y] << ")->" << place[_y];
        return;
    }
    output(_x, path[_x][_y]);
    output(path[_x][_y], _y); 
}

void workR(){
    scanf("%d",&R);
    while(R--){
        string p1,p2;
        cin>>p1>>p2;
        int x = getNum(p1),y = getNum(p2);
        if(x==y){
            cout<<place[x]<<endl;
            continue;
        }
        cout<<place[x];
        output(x,y);
        cout<<endl;
    }
}

int main(){
    workP();
    //debug();
    workQ();
    workR();
    //system("pause");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章