最短路径
Description
Rocking is a fat boy, and he does not like walking at all. Whenever he goes somewhere, he always tries to find a bus to take. But he lives in a city where he can not go everywhere by bus. So, he wants you to help him find the best way to his destination, which has the shortest distance for him to walk.
Remember the places in the city are numbered from 0 to N-1.
Input
Input consists of T cases, with T in the first line.
In each case, the first line contains two integers, N(2<=N<=100),the number of the places in Rocking's city, and M(0<=M<=N*(N-1)/2), the number of the roads.
The next M lines each contains four integers: a,b,c,d(0<=a,b The last line contains two integers s,t(0<=s,tOutput
For each case, output a integer in a single line, indicating the shortest distance he must walk. Note that Rocking can take as many buses as he wants, and he only focus on the roads he must walk on.
If he can not get to his destination, please output -1.
大概意思就是能
take bus
的edge
的weight
为0, 然后找出一条最短路径的cost
.
下面给出Dijkstra和Floyd的代码
#include <stdio.h>
#include <iostream>
#include <list>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <string.h>
using namespace std;
const int N = 102;
const int M = N * N;
const int INF = 100000;
bool visit[N];
int edge[N][N];
int dist[N];
int parent[N];
// m: number of edge
// n: number of vertices
void init(const int m, const int n) {
// memset(edge, INF, sizeof(edge));
// memset(edge, INF, M * sizeof(int));
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i == j) {
edge[i][j] = 0;
continue;
}
edge[i][j] = INF;
}
}
int u, v, c, flag;
for(int i = 0; i < m; i++) {
cin >> u >> v >> c >> flag;
edge[u][v] = flag != 0 ? 0 : c;
edge[v][u] = edge[u][v];
}
}
// m: number of edge
// n: number of vertices
// s: index of start place
// e: index destination
void dijkstra(const int m, const int n, const int s,
const int e, const bool isPath = false)
{
for(int i = 0; i < n; i++) {
dist[i] = i == s ? 0 : INF;
parent[i] = -1;
}
//
memset(visit, false, sizeof(visit));
/*
n iteration because there are n vertices
each iteration t, select the t th vertex whose cost is t th smallest,
then refresh the weights beteen it and other vertices
*/
for(int i = 0; i < n; i++) {
int u = -1, c = INF;
for(int j = 0; j < n; j++) {
if(!visit[j] && dist[j] <= c) {
u = j;
c = dist[j];
}
}
if(u == -1) {
continue;
// exit(1);
}
visit[u] = true;
// relax, at the same time, record the path
for(int v = 0; v < n; v++) {
if(dist[v] > dist[u] + edge[u][v]) {
dist[v] = dist[u] + edge[u][v];
parent[v] = u;
}
}
}
if(dist[e] < INF) {
std::cout << dist[e] << endl;
}
if(isPath) {
int v = e;
std::cout << "end <- ";
while(parent[v] != -1) {
std::cout << v << " <- ";
v = parent[v];
}
std::cout << v << " <- start" << std::endl;
}
}
int main() {
/*
test case:
1
5 6
0 1 10 1
1 2 20 1
2 4 2 0
0 3 1 0
3 4 2 0
0 2 40 1
0 4
ans: 2
*/
int T;
cin >> T;
while(T--) {
int m, n;
int s, e;
// get the numbers of vertices and edges
cin >> n >> m;
// inti the edges or weights and something else
init(m, n);
// get start place and destination
cin >> s >> e;
bool isPath = true;
// find the shortest path and its corresponding cost
dijkstra(m, n, s, e, isPath);
}
}
#include <stdio.h>
#include <iostream>
#include <list>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <string.h>
using namespace std;
const int N = 102;
const int M = N * N;
const int INF = 100000;
bool visit[N];
int edge[N][N];
// m: number of edge
// n: number of vertices
void init(const int m, const int n) {
// memset(edge, INF, sizeof(edge));
// memset(edge, INF, M * sizeof(int));
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i == j) {
edge[i][j] = 0;
continue;
}
edge[i][j] = INF;
}
}
memset(visit, false, sizeof(visit));
int u, v, c, flag;
for(int i = 0; i < m; i++) {
cin >> u >> v >> c >> flag;
edge[u][v] = flag ? 0 : c;
edge[v][u] = edge[u][v];
}
}
// m: number of edge
// n: number of vertices
void Floyd(const int m, const int n) {
for(int k = 0; k < n; k++) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
// if(edge[i][j] < INF && edge[i][k] < INF && edge[k][j] < INF) {
// error
// if(edge[i][j] <= INF && edge[i][k] <= INF && edge[k][j] <= INF) {
// right, but no meaning
// if(edge[i][j] < INF && edge[k][j] < INF) {
// error
if(edge[i][j] < INF && edge[k][j] < INF) {
// right
if(edge[i][j] > edge[i][k] + edge[k][j]) {
edge[i][j] = edge[i][k] + edge[k][j];
edge[j][i] = edge[i][j];
}
}
}
}
}
}
int main() {
/*
test case:
1
5 6
0 1 10 1
1 2 20 1
2 4 2 0
0 3 1 0
3 4 2 0
0 2 40 1
0 4
ans: 2
*/
int T;
cin >> T;
while(T--) {
int m, n;
int s, e;
// get the numbers of vertices and edges
cin >> n >> m;
// inti the edges or weights and something else
init(m, n);
// get start place and destination
cin >> s >> e;
std::cout << "s: " << s << ", e: " << e << std::endl;
// find the shortest path and its corresponding cost
Floyd(m, n);
int cost = edge[s][e];
if(cost < INF) {
std::cout << cost << std::endl;
} else {
std::cout << "failed: ";
std::cout << -1 << std::endl;
}
}
}