poj-1502(MPI Maelstrom)

今天下午做了這道題,印象有點深刻(題目那麼鬼長)。

題目大意:前面描述各種高大上,看到描述最後一段以及Output和樣例之後才明白或來,個人感覺前面描述有點囉嗦。這道題說的是有n個處理器,問從第一個處理器發送信息到其他處理器所需的最短時間是多少。然後給你一個下三角矩陣,注意對角線爲0(沒給出)。

大體思路:從題目和樣例可以看出這是一道求最短路徑的題,而且就只考最短路徑,可以想到用Dijkstra算法來求,建議先理解算法,自己敲,不要套什麼模板。算出第一個點到其它點的最短路徑後,取出其中的最大值就是題目所要求的最短時間。

我下面用兩種方法,第一種用鄰接矩陣,第二種用鄰接表。

1.鄰接矩陣 ac代碼  複雜度O(n^2)

#include<iostream>
#include<string>
#include<stdio.h>
#include<cstring>
using namespace std;

const int INF=100000000;
const int maxn=105;
int box[maxn][maxn];  //記錄無向圖
int sum;

void dijkstra(int n){
    int vis[maxn];
    int cost[maxn];
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
        cost[i]=box[1][i];
    vis[1]=1;
    for(int i=2;i<=n;i++){
        int m=INF;
        int next;
        for(int j=1;j<=n;j++)
            if(!vis[j]&&cost[j]<m){
                m=cost[j];
                next=j;
            }
        vis[next]=1;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&(box[next][j]+cost[next])<cost[j])
                cost[j]=box[next][j]+cost[next];
        }
    }
    sum=0;
    for(int i=1;i<=n;i++)
        if(cost[i]!=INF)
            sum=max(sum,cost[i]);
}
int main(){
    int n;
    while(cin>>n){
        string temp;
        //先將下三角矩陣還原
        for(int i=1;i<=n;i++){
            box[i][i]=INF;
            for(int j=1;j<i;j++){
                cin>>temp;
                if(temp=="x")
                    box[i][j]=box[j][i]=INF;
                else{
                    int sum=0;
                    for(int k=0;temp[k];k++)
                        sum=sum*10+temp[k]-'0';
                    box[j][i]=box[i][j]=sum;
                }
            }
        }
        dijkstra(n);
        cout<<sum<<endl;
    }
    return 0;
}



2.鄰接表 ac代碼 複雜度O(E+n)

#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
#include<string>
using namespace std;

const int inf=1000000;
const int maxn=105;

struct Edge{  //記錄邊
    int to;  //邊指向的結點
    int dist;  //邊的長度
    friend bool operator < (Edge a,Edge b){
        return a.dist>b.dist;
    }
};
vector<Edge> E;   //存儲邊
vector<int> G[maxn];  //鄰接表
int sum;

void addEdge(int from,int to,int dist){  //建立鄰接表
    E.push_back((Edge){to,dist});
    G[from].push_back(E.size()-1);
}

void dijkstra(int s,int n){
    int vis[maxn];  //記錄訪問節點
    int dis[maxn];
    memset(vis,0,sizeof(vis));
    for(int i=0;i<n;i++)
        dis[i]=inf;
    priority_queue<Edge> q;
    q.push((Edge){s,0});
    dis[s]=0;
    while(!q.empty()){
        Edge e=q.top();
        q.pop();
        int curnode=e.to;
        int curdist=e.dist;
        if(vis[curnode])
            continue;
        vis[curnode]=1;
        for(int i=0;i<G[curnode].size();i++){
            Edge e=E[G[curnode][i]];
            if(curdist+e.dist<dis[e.to]){
                dis[e.to]=curdist+e.dist;
                q.push((Edge){e.to,dis[e.to]});
            }
        }
    }
    sum=0;
    for(int i=0;i<n;i++)
        sum=max(sum,dis[i]);
}

int main(){
    int n;
    cin>>n;
    int from,to;
    string dist;
    for(int i=0;i<n;i++){
        for(int j=0;j<i;j++){
            cin>>dist;
            if(dist=="x"){
                addEdge(j,i,inf);
                addEdge(i,j,inf);
            }
            else{
                int num=0;
                for(int k=0;dist[k];k++)
                    num=num*10+dist[k]-'0';
                addEdge(i,j,num);
                addEdge(j,i,num);
            }
        }
    }
    dijkstra(0,n);
    cout<<sum<<endl;
    return 0;
}




發佈了39 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章