lightOJ 1002:Country Roads

大意是给定若干个城市,若干条道路,其中有一个城市是“我”的家,求从各个城市到达家的所有道路中的最短道路中的花费最大的一段路。


用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);
				}
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值