字典序最小的最短路

问题描述:

给出n和m,有n个点,m条双向边,1为起点,n为终点,每条边都有一个权值,经过每一条边的时间都为1,求从起点到终点既要时间最少,又要权值组成的序列的字典序最小的一条路径.

输入样例:

4 6
1 2 1
1 3 2
3 4 3
2 3 1
2 4 4 
3 1 1

输出样例:

2
1 3

限制范围:

50%,n<=100
100%,n<=100000,m<=200000

分析:

又是一道双关键字限制结果最优性的问题,此类问题一般思路就是枚举一个,计算最优另一个。
对于这道题,我们可以先用SPFA算出从终点开始到每个点的距离,然后从起点开始,每一步都选择权值最小的即可。其实也不是很复杂。

参考程序:

#include
#include
#include
#include
#include
using namespace std;
const int maxn=610000;
const int INF=0x3f3f3f3f;
struct Edge{
	int j,v,next;
}e[maxn];
int EdgeCnt=0;
int d[maxn],a[maxn];
bool inq[maxn];
queue Q;
int n,m;
void addedge(int u,int v,int w){
	int p=++EdgeCnt;
	e[p].j=v;e[p].v=w;e[p].next=a[u];
	a[u]=p;
}
int main(){
	freopen("ideal.in","r",stdin);
	freopen("ideal.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=0;id[u]+1){
				d[j]=d[u]+1;
				if (!inq[j]){
					inq[j]=true;
					Q.push(j);
				}
			}
		}
		inq[u]=false;
	}
	printf("%d\n",d[1]);
	set now,next;
	now.insert(1);
	for (int dist=d[1]-1;dist>=0;dist--){
		int col=INF;
		for (set::iterator u=now.begin();u!=now.end();u++){
			for (int p=a[*u];p;p=e[p].next){
				int j=e[p].j,v=e[p].v;
				if (d[j]==dist && v<=col){
					if (v


你可能感兴趣的:(字典序最小的最短路)