输入样例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;
}