今天下午做了这道题,印象有点深刻(题目那么鬼长)。
题目大意:前面描述各种高大上,看到描述最后一段以及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;
}