poj-1502(MPI Maelstrom)

本文介绍了一道关于求解最短路径的问题,并通过两种不同的数据结构实现Dijkstra算法,包括邻接矩阵和邻接表,展示了如何求解从一个源点到其他所有点的最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天下午做了这道题,印象有点深刻(题目那么鬼长)。

题目大意:前面描述各种高大上,看到描述最后一段以及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;
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值