最短路径问题

点击打开链接

类似A strange lift的写法,之前一直返回RE,感觉有点不科学,数据较小。后来看discuss,居然输入还要考虑去重。

题意:略;

解析:最短路问题,但是有两种情况,因此需要根据具体情况来考虑。我采用的是构造两张图,然后在使用Dijkstra中将dis与cost放在一个结构体中,便于理解。其它就是A strange lift的一点变形

#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;

const int Max = 0xfffffff;
const int maxn = 1005;

struct node{
	int dis, cost;
}edge[ maxn ];
int mapp1[ maxn ][ maxn ], mapp2[ maxn ][ maxn ], vis[ maxn ];
int n, m, start, end, a, b, d, p;

void Dijkstra( int start ){
	memset( vis, 0, sizeof( vis ) );
	vis[ start ] = 1;
	for( int i = 1; i <= n; ++i ){
		edge[ i ].dis = mapp1[ start ][ i ];
		edge[ i ].cost = mapp2[ start ][ i ];
	}
	edge[ start ].dis = edge[ start ].cost = 0;
	
	for( int i = 1; i <= n; ++i ){
		int tempa = Max, tempb = Max, k;
		for( int j = 1; j <=n; ++j ){
			if( !vis[ j ] && ( ( tempa > edge[ j ].dis ) || ( ( tempa == edge[ j ].dis ) && ( tempb > edge[ j ].cost ) ) ) ){
				tempa = edge[ j ].dis;
				tempb = edge[ k = j ].cost;
			}
		}
		vis[ k ] = 1;
		for( int j = 1; j <= n; ++j ){
			if( !vis[ j ] && ( ( edge[ j ].dis > edge[ k ].dis + mapp1[ k ][ j ] ) || ( ( edge[ j ].dis == edge[ k ].dis + mapp1[ k ][ j ] ) && ( edge[ j ].cost > edge[ k ].cost + mapp2[ k ][ j ] ) ) ) ){
				edge[ j ].dis = edge[ k ].dis + mapp1[ k ][ j ];
				edge[ j ].cost = edge[ k ].cost + mapp2[ k ][ j ];		
			}
		}
	}
}

int main(){
	while( scanf( "%d%d", &n, &m ) != EOF ){
		if( !n && !m )
			break;
		for( int i = 0; i <= n; ++i ){
			edge[ i ].dis = edge[ i ].cost = Max;
			for( int j =0; j <= n; ++j ){
				mapp1[ i ][ j ] = Max;
				mapp2[ i ][ j ] = Max;
			}
		}
		for( int i = 0; i < m; ++i ){
			scanf( "%d%d%d%d", &a, &b, &d, &p );
			if( ( mapp1[ a ][ b ] > d ) || ( ( mapp1[ a ][ b ] == d ) && ( mapp2[ a ][ b ] > p ) ) ){
				mapp1[ a ][ b ] = mapp1[ b ][ a ] = d;
				mapp2[ a ][ b ] = mapp2[ b ][ a ] = p;
			}
		}
		scanf( "%d%d", &start, &end );
		Dijkstra( start );
		printf( "%d %d\n", edge[ end ].dis, edge[ end ].cost );
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值