大意是给定若干个城市,若干条道路,其中有一个城市是“我”的家,求从各个城市到达家的所有道路中的最短道路中的花费最大的一段路。
用dijkstra算法做,只要把原来的判断条件改一改就行了。至于航神说的方法,判断条件dis[j]>当前边,我觉得是不能过的吧。不过航神嘛,总有办法的。最后的赋值语句参考了松神的代码,学到了好多。这道题一开始是用spfa做的,当时过样例的时候有点问题,后来就改为dijkstra,现在感觉spfa也能做,就先不写了。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int inf=1<<20;
int n,m,s;
int map[505][505];
int dis[505];
bool had[505];
void init(){
for(int i=0;i<=n;i++){
for(int j=i+1;j<=n;j++){
map[i][j]=map[j][i]=inf;
}
}
}
int Max(int a,int b){
return (a>b)?a:b;
}
int Min(int a,int b){
return (a<b)?a:b;
}
void dijkstra(){
for(int i=0;i<n;i++){
dis[i]=map[s][i];
had[i]=0;
}
had[s]=1;dis[s]=0;
for(int i=1;i<=n;i++){
int mm=-1;
int minn=inf;
for(int j=0;j<n;j++){
if(!had[j] && dis[j]<minn){
minn=dis[mm=j];
}
}
if(mm==-1) break;
had[mm]=1;
for(int j=0;j<n;j++){
if(!had[j] && dis[j]>Max(map[mm][j],dis[mm])){
dis[j]=Max(map[mm][j],dis[mm]);
}
}
}
}
int main(){
//freopen("in.txt","r",stdin);
int T;
cin>>T;
for(int I=1;I<=T;I++){
cin>>n>>m;
init();
while(m--){
int a,b,c;
cin>>a>>b>>c;
if(map[a][b]>c) map[a][b]=map[b][a]=c;
}
cin>>s;
dijkstra();
printf("Case %d:\n",I);
for(int i=0;i<n;i++){
if(dis[i]!=inf) cout<<dis[i]<<endl;
else cout<<"Impossible\n";
}
}
return 0;
}
之后试了一下,果然spfa也是可以做的嘛,以下贴出spfa片段的代码,只要把上面的dijkstra函数部分改成下面的spfa函数,然后加上队列q,main函数里调用dijkstra改为调用spfa就行了
void spfa(){
for(int i=0;i<n;i++){
dis[i]=inf;
had[i]=0;
}
had[s]=1;dis[s]=0;
q.push(s);
while(!q.empty()){
int t=q.front(); q.pop();
had[t]=0;
for(int i=0;i<n;i++){
if(!map[t][i] || map[t][i]==inf) continue;
if(dis[i]>Max(dis[t],map[t][i])){
dis[i]=Max(dis[t],map[t][i]);
if(!had[i]){
had[i]=1;
q.push(i);
}
}
}
}
}