今天下午做了這道題,印象有點深刻(題目那麼鬼長)。
題目大意:前面描述各種高大上,看到描述最後一段以及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;
}