7-13 天梯地图

 

输入样例1:

10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
5 4 0 2 3
5 9 1 1 4
0 6 0 1 1
7 3 1 1 2
8 3 1 1 2
2 5 0 2 2
2 1 1 1 1
1 5 0 1 3
1 4 0 1 1
9 7 1 1 3
3 1 0 2 5
6 3 1 2 1
5 3

输出样例1:

Time = 6: 5 => 4 => 8 => 3
Distance = 3: 5 => 1 => 3

输入样例2:

7 9
0 4 1 1 1
1 6 1 3 1
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 3 1
3 2 1 2 1
4 5 0 2 2
6 5 1 2 1
3 5

输出样例2:

Time = 3; Distance = 4: 3 => 2 => 5

斯米嘛噻,米娜桑!!好久没更新了!!!

前段时间一直在做其他的事情算法有些搁置了,但是这两年还是不会放手的

这个题目的话就是纯暴力dij,我写了两遍dij,然后一发过了,非常开心哈哈,特地记录一下!!

#include "bits/stdc++.h"
using namespace std;
const int N = 600;
vector<int> g[N];
struct n_node{
	int id;
	int ti;
	int dis;
	n_node(int a, int b, int c){
		id = a, ti = b, dis= c;
	}
	bool operator < (const n_node & t) const {
		if(ti != t.ti) return ti > t.ti;
		else return dis > t.dis;
	}
}; //找最短时间的结构体 
struct node{
	int id, dis, num;
	node(int a, int b, int c){
		id = a, dis = b, num = c;
	}
	bool operator < (const node & t) const{
		if(dis != t.dis) return dis > t.dis;
		else return num > t.num;
	}
}; //找最短距离的结构体
int distance1[N][N];//两地距离 
int timee[N][N];//两地时间 
int n, m;
int dis[N];//从起点到某地的最短距离 
int ti[N];//从起点到某地的最短时间 
int numm[N];//从起点到某地的最短距离相同时经过的最少地点数 
int done[N];//已经经过的地点 
int pre[N]; //寻找最短时间的路径记录 
int pre1[N];//寻找最短距离的路径记录 

void di1(int s) //找最短时间 
{
	priority_queue<n_node> q;
	memset(done, 0, sizeof(done));
	memset(dis, 0x3f3f3f, sizeof(dis));
	memset(ti, 0x3f3f3f, sizeof(ti));
	dis[s] = 0, ti[s] = 0;
	q.push(n_node(s, ti[s], dis[s]));
	while(q.size()){
		n_node t = q.top();
		q.pop();
		int id1 = t.id;
		int ti1 = t.ti;
		int dis1 = t.dis;	
		if(done[id1]) continue;
		done[id1] = 1;
		for(int i = 0; i < g[id1].size(); i ++){
			int id2 = g[id1][i];
			int dis2 = distance1[id1][id2];
			int ti2 = timee[id1][id2];
			if(done[id2]) continue;
			if(ti1 + ti2 < ti[id2] || ti1 + ti2 == ti[id2] && dis1 + dis2 < dis[id2]){
				ti[id2] = ti1 + ti2 ,dis[id2] = dis1 + dis2, pre[id2] = id1;
				q.push(n_node(id2, ti[id2], dis[id2]));
			}  
		}
	}
}
void di2(int s){ //找最短距离 
	priority_queue<node> q;
	memset(done, 0, sizeof(done));
	memset(dis, 0x3f3f3f, sizeof(dis));
	memset(numm, 0x3f3f3f, sizeof(numm));
	dis[s] = 0, numm[s] = 0;
	q.push(node(s, dis[s], numm[s]));
	while(q.size()){
		node t = q.top();
		q.pop();
		int id1 = t.id;
		int num1 = t.num;
		int dis1 = t.dis;	
		if(done[id1]) continue;
		done[id1] = 1;
		for(int i = 0; i < g[id1].size(); i ++){
			int id2 = g[id1][i];
			int dis2 = distance1[id1][id2];
			if(done[id2]) continue;
			if(dis1 + dis2 < dis[id2] || dis1 + dis2 == dis[id2] && num1 + 1 < numm[id2]){
				dis[id2] = dis1 + dis2, pre1[id2] = id1, numm[id2] = num1 + 1;
				q.push(node(id2,dis[id2], numm[id2]));
			}  
		}
	}
}
int main(){
	cin>>n>>m;
	int a, b;
	int one_way, length, tim;
	memset(distance1, 0x3f3f3f, sizeof(distance1)); //距离先设成无限,代表不通 
	while(m--){
		cin>>a>>b>>one_way>>length>>tim;
		g[a].push_back(b);	
		distance1[a][b] = length;
		timee[a][b] = tim;
		if(one_way == 0){
			g[b].push_back(a);
			distance1[b][a] = length;
			timee[b][a] = tim;
		} 
	}
	int begin, end;
	cin>>begin>>end;
	di1(begin);
	di2(begin); //两次dij最短路搞定
	 
	//算法核心就到这边,下面都是输出 
	vector<int> v, w;
	int t1 = end, t2 = end;
	v.push_back(t1);
	while(pre[t1] != begin){
		v.push_back(pre[t1]);
		t1 = pre[t1];
	}
	v.push_back(begin);
	w.push_back(t2);
	while(pre1[t2] != begin){
		w.push_back(pre1[t2]);
		t2 = pre1[t2];
	}
	w.push_back(begin);
	reverse(v.begin(), v.end());
	reverse(w.begin(), w.end());
	int flag = 0;
	if(v == w) flag = 1;
	if(flag == 1){
		int ans1 = ti[end];
		int ans2 = dis[end];
		cout<<"Time = "<<ans1<<"; Distance = "<<ans2<<": ";
		for(int i = 0; i < v.size(); i ++){
			cout<<v[i];
			if(i != v.size() - 1) cout<<" => ";
		}
		return 0;
	} 
	int ans1 = ti[end];
	cout<<"Time = "<<ans1<<": ";
	for(int i = 0; i < v.size(); i ++){
		cout<<v[i];
		if(i != v.size() - 1) cout<<" => ";
	}
	cout<<endl; 
	ans1 = dis[end];
	cout<<"Distance = "<<ans1<<": ";	
	for(int i = 0; i < w.size(); i ++){
		cout<<w[i];
		if(i != w.size() - 1) cout<<" => ";
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小竹子14

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值