PAT - 甲级 - 1111 Online Map

Nothing to fear


种一棵树最好的时间是十年前,其次是现在!

那些你早出晚归付出的刻苦努力,你不想训练,当你觉的太累了但还是要咬牙坚持的时候,那就是在追逐梦想,不要在意终点有什么,要享受路途的过程,或许你不能成就梦想,但一定会有更伟大的事情随之而来。 mamba out~


人一我十,人十我百,追逐青春的梦想,怀着自信的心,永不言弃!

Online Map

考点: Dijkstra记录最短路,和dfs

题目大意

求出时间最短的一条路径和距离最短的路径,其实就是进行两次dijkstra,然后进行两组dfs没什么特别的,写的时候认真写就ok啦

分析

需要注意的点:

完整代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;
const int N = 505;
int n , m , start , target;
int e[N][N] , t[N][N];
int dist[N] , disd[N] , vis[N];
vector<int> pret[N] , pred[N], patht ,pathd;
int timecost = 99999999, minint = 0x3f;
priority_queue<pair<int ,int> > q;
void dfs_dis(int now,vector<int> tmp)
{
	if(now == start)
	{
		tmp.push_back(now);
		int cost = 0;
		for(int i = tmp.size() - 1;i > 0;i --)
		{
			int a = tmp[i] , b = tmp[i-1];
			cost += t[a][b];
		}
		if(cost < timecost){
			pathd = tmp;
			timecost = cost;
		}
	}
	for(int i = 0;i < pred[now].size();i ++)
	{
		tmp.push_back(now);
		dfs_dis(pred[now][i] , tmp);
		tmp.pop_back();
	}
}
void dfs_time(int now,vector<int> tmp)
{
	if(now == start)
	{
		tmp.push_back(now);
		if(patht.size() == 0)
			patht = tmp;
		else{
			if(patht.size() > tmp.size()){
				patht = tmp;
			}
		}
	}
	for(int i = 0;i < pret[now].size();i ++)
	{
		tmp.push_back(now);
		dfs_time(pret[now][i] , tmp);
		tmp.pop_back();
	}
}
void Dijkstra(int s , int (&dis)[N], vector<int> (&pre)[N], int flag)
{
	memset(dis , 0x3f , sizeof dis);
	memset(vis , 0 , sizeof vis);
	dis[s] = 0;
	q.push({0 , s});
	while(!q.empty())
	{
		int x = q.top().second;q.pop();
		if(vis[x])continue;
		vis[x] = 1;
		for(int i = 0;i < n;i ++)
		{
			int y = i , w;
			if(flag)w = e[x][i];
			else w = t[x][i];
			if(vis[y])continue;
			if(dis[y] > dis[x] + w)
			{
				pre[y].clear();
				pre[y].push_back(x);
				dis[y] = dis[x] + w;
				q.push({-dis[y] , y});
			}else if(dis[y] == dis[x] + w){
				pre[y].push_back(x);
			}
		}
	}
}
bool check()
{
	if(pathd.size() != patht.size())return false;
	for(int i = 0;i < patht.size();i ++)
		if(patht[i] != pathd[i])return false;
	return true;
}
void Output()
{
	if(check())
	{
		printf("Distance = %d; Time = %d:",disd[target],dist[target]);
		printf(" %d",patht[patht.size() - 1]);
		for(int i = patht.size() - 2;i >=0 ;i--)
			printf(" -> %d", patht[i]);
	}else{
		printf("Distance = %d:", disd[target]);
		printf(" %d",pathd[pathd.size() - 1]);
		for(int i = pathd.size() - 2;i >=0 ;i--)
			printf(" -> %d", pathd[i]);
		printf("\nTime = %d:",dist[target]);
		printf(" %d",patht[patht.size() - 1]);
		for(int i = patht.size() - 2;i >=0 ;i--)
			printf(" -> %d", patht[i]);
	}
}
int main()
{
	memset(e , 0x3f , sizeof e);
	memset(t , 0x3f , sizeof t);
	cin >> n >> m;
	int a , b , c , d , oneway;
	for(int i = 0;i < m;i ++)
	{
		scanf("%d %d %d %d %d",&a,&b, &oneway ,&c,&d);
		if(oneway){
			e[a][b] = c;
			t[a][b] = d;
		} else {
			e[a][b] = e[b][a] = c;
			t[a][b] = t[b][a] = d;
		}
	}
	cin >> start >> target;
	Dijkstra(start , disd , pred , 1);
	dfs_dis(target , vector<int> ());
	Dijkstra(start , dist , pret , 0);
	dfs_time(target , vector<int> ());
	Output();
	return 0;
}
posted @ 2020-07-16 09:25  _starsky  阅读(121)  评论(0编辑  收藏  举报