图论 - 最短路径算法

1342:【例4-1】最短路径问题
  • 深搜
#include <bits/stdc++.h>
using namespace std;

const int N = 105;
int n, m, s, t;
struct node{
	int x, y;
	double len;
}p[N];
double e[N][N], ans = 1e9;

void dfs(int i, double dis) {
	if (dis >= p[i].len) return;
	p[i].len = dis;
	
	if (i == t) {
		ans = min(ans, p[i].len);
		return ;
	}

	for (int j = 1; j <= n; j ++) {
		if (e[i][j] > 0) {
			dfs(j, dis + e[i][j]);
		}
	}
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i ++) {
		scanf("%d%d", &p[i].x, &p[i].y);
		p[i].len = 1E9;
	}
	
	scanf("%d", &m);
	for (int i = 1; i <= m; i ++) {
		int a, b;
		scanf("%d%d", &a, &b);
		double len = pow(p[a].x - p[b].x, 2) + pow(p[a].y - p[b].y, 2);
		e[a][b] = e[b][a] = sqrt(len);
	}
	
	scanf("%d%d", &s, &t);
	dfs(s, 0);
	printf("%.2f\n", ans);
	
	return 0;
}
  • floyd
#include <bits/stdc++.h>
using namespace std;

const int N = 105;
int n, m, s, t;
struct node{
	int x, y;
}p[N];
double e[N][N];

void floyd() {
	for (int k = 1; k <= n; k ++) 
		for (int i = 1; i <= n; i ++) 
			for (int j = 1; j <= n; j ++) 
				e[i][j] = min(e[i][j], e[i][k]+e[k][j]);
}

int main() {
	cin >> n;
	for (int i = 1; i <= n; i ++) cin >> p[i].x >> p[i].y;
	
	memset(e, 0x7f, sizeof(e));
	cin >> m;
	for (int i = 1; i <= m; i ++) {
		int a, b;
		cin >> a >> b;
		double len = pow(p[a].x - p[b].x, 2) + pow(p[a].y - p[b].y, 2);
		e[a][b] = e[b][a] = sqrt(len);
	}
	
	cin >> s >> t;	
	floyd();
	printf("%.2f\n", e[s][t]);
	
	return 0;
}
  • dijkstra
#include <bits/stdc++.h>
using namespace std;

const int N = 105;
int n, m, s, t;
struct node{
	int x, y;
}p[N];
double e[N][N];
bool vst[N];

void dijkstra() {
	vst[s] = true;
	
	for (int i = 2; i <= n; i ++) {
		int t = 0;
		for (int j = 1; j <= n; j ++) {
			if (!vst[j] && e[s][j] < e[s][t]) t = j;
		}
		vst[t] = true;
		
		for (int j = 1; j <= n; j ++) {
			if (!vst[j]) e[s][j] = min(e[s][j], e[s][t]+e[t][j]);
		}
	}	
}

int main() {
	cin >> n;
	for (int i = 1; i <= n; i ++) cin >> p[i].x >> p[i].y;
	
	memset(e, 0x7f, sizeof(e));
	cin >> m;
	for (int i = 1; i <= m; i ++) {
		int a, b;
		cin >> a >> b;
		double len = pow(p[a].x - p[b].x, 2) + pow(p[a].y - p[b].y, 2);
		e[a][b] = e[b][a] = sqrt(len);
	}
	
	cin >> s >> t;	
	dijkstra();
	printf("%.2f\n", e[s][t]);
	
	return 0;
}
  • bellman_ford
#include <bits/stdc++.h>
using namespace std;

const int N = 105;
int n, m, s, t;
double dis[N];

struct node {
	int x, y;
}p[N];

struct edge {
	int u, v; 
	double w;
}e[11000];

void bellman_ford() {
	memset(dis, 0x7f, sizeof(dis));
	dis[s] = 0;
	
	for (int i = 1; i < n; i ++) {
		for (int j = 1; j <= 2 * m; j ++) {
			int u = e[j].u, v = e[j].v;
			double w = e[j].w;
			dis[v] = min(dis[v], dis[u] + w);
		}
	}	
}

int main() {
	cin >> n;
	for (int i = 1; i <= n; i ++) cin >> p[i].x >> p[i].y;
	cin >> m;
	for (int i = 1; i <= m; i ++) {
		int u, v;
		cin >> u >> v;
		double w = pow(p[u].x - p[v].x, 2) + pow(p[u].y - p[v].y, 2);
		w = sqrt(w);
		e[2 * i - 1] = {u, v, w};
		e[2 * i] = {v, u, w};
	}
	
	cin >> s >> t;
	bellman_ford();
	printf("%.2f", dis[t]);
	
	return 0;
}
1344:【例4-4】最小花费
#include <bits/stdc++.h> 
using namespace std;

const int N = 2010;
int n, m, a, b;
double e[N][N];
bool vst[N];

void dijkstra() {
	vst[a] = true;
	for (int i = 1; i < n; i ++) {
		int t = 0;
		for (int j = 1; j <= n; j ++) {
			if (!vst[j] && e[a][j] > e[a][t]) t = j;
		}
		vst[t] = true;
		
		for (int j = 1; j <= n; j ++) {
			if (!vst[j]) e[a][j] = max(e[a][j], e[a][t] * e[t][j]);
		}
	}
}

int main() {
	cin >> n >> m;
	while (m --) {
		int x, y, z;
		cin >> x >> y >> z;
		e[x][y] = e[y][x] = (100 - z) / 100.0;
	}

	cin >> a >> b;
	dijkstra();
	printf("%.8f", 100 / e[a][b]);
	
	return 0;
}
1345:【例4-6】香甜的黄油
#include <bits/stdc++.h> 
using namespace std;

const int N = 1000;
int e[N][N], a[N];
int n, p, c;

void floyd() {
	for (int k = 1; k <= p; k ++) 
		for (int i = 1; i <= p; i ++)  
			for (int j = 1; j <= p; j ++) 
				e[i][j] = min(e[i][j], e[i][k] + e[k][j]);
}

int main() {
	memset(e, 0x3f, sizeof(e));
	
	cin >> n >> p >> c;
	for (int i = 1; i <= n; i ++) cin >> a[i];

	for (int i = 1; i <= c; i ++) {
		int u, v, w;
		cin >> u >> v >> w;
		e[u][v] = e[v][u] = w;
	}

	floyd();
	
	//枚举p个牧场,打擂台找到某一个牧场,
	//使得所有奶牛到这个牧场的路程之和最小 
	int minn = 1e9;
	for (int i = 1; i <= p; i++) {
		int sum = 0;
		for (int j = 1; j <= n; j ++) {
			if (a[j] != i) sum += e[i][a[j]];
		}
		minn = min(minn, sum);
	}
	cout << minn;
	
	return 0;
}
1376:信使(msner)
  • floyd
#include <bits/stdc++.h> 
using namespace std;

const int N = 105;
int n, m, e[N][N];

void floyd() {
	for (int k = 1; k <= n; k ++) 
		for (int i = 1; i <= n; i ++)  
			for (int j = 1; j <= n; j ++) 
				e[i][j] = min(e[i][j], e[i][k] + e[k][j]);
}

int main() {
	memset(e, 0x3f, sizeof(e));
	
	cin >> n >> m;
	while (m --) {
		int u, v, w;
		cin >> u >> v >> w;
		e[u][v] = e[v][u] = w;
	}

	floyd();
	
	int ans = 0;
	for (int i = 2; i <= n; i++) {
		if (e[1][i] == 0x3f3f3f3f) {
			cout << -1 << endl;
			return 0;
		}
		ans = max(ans, e[1][i]);
	}
	cout << ans;
	
	return 0;
}
  • dijkstra
#include <bits/stdc++.h> 
using namespace std;

const int N = 105;
int n, m, e[N][N];
bool vst[N];

void dijkstra() {
	vst[1] = true;
	
	for (int i = 1; i < n; i ++) {
		int t = 0;
		for (int j = 1; j <= n; j ++) {
			if (!vst[j] && e[1][j] < e[1][t]) t = j;
		}
		vst[t] = true;
		
		for (int j = 1; j <= n; j ++) {
			if (!vst[j]) e[1][j] = min(e[1][j], e[1][t] + e[t][j]);
		}
	}
}

int main() {
	memset(e, 0x3f, sizeof(e));
	
	cin >> n >> m;
	while (m --) {
		int u, v, w;
		cin >> u >> v >> w;
		e[u][v] = e[v][u] = w;
	}

	dijkstra();
	
	int ans = 0;
	for (int i = 2; i <= n; i++) {
		if (e[1][i] == 0x3f3f3f3f) {
			cout << -1 << endl;
			return 0;
		}
		ans = max(ans, e[1][i]);
	}
	cout << ans;
	
	return 0;
}
1377:最优乘车(travel)
  • 字符输入
#include <bits/stdc++.h> 
using namespace std;

const int N = 510;
int n, m, e[N][N], a[N];

void floyd() {
	for (int k = 1; k <= n; k ++) 
		for (int i = 1; i <= n; i ++)  
			for (int j = 1; j <= n; j ++) 
				e[i][j] = min(e[i][j], e[i][k] + e[k][j]);
}

int main() {
 	memset(e, 0x3f, sizeof(e));
 	
 	scanf("%d%d\n", &m, &n); 	
 	while (m --) {
 		int num = 0, cnt = 0;
 		char ch;
 		while (scanf("%c", &ch)) {
			if (ch >= '0' && ch <= '9') {
				num = num * 10 + ch - '0';
			}
			else {
				a[++ cnt] = num;
				num = 0;
 				if (ch == '\n') break;
			}
		}
		
 		for (int i = 1; i <= cnt; i ++) {
 			for (int j = i + 1; j <= cnt; j ++) {
 				e[a[i]][a[j]] = 1;
			}
 		}
	}
	
	floyd();
	
	if (e[1][n] == 0x3f3f3f3f) cout << "NO";
	else cout << e[1][n] - 1;
	
	return 0;
}
  • 字符串输入
#include <bits/stdc++.h> 
using namespace std;

const int N = 510;
int n, m, e[N][N], a[N];

void floyd() {
	for (int k = 1; k <= n; k ++) 
		for (int i = 1; i <= n; i ++)  
			for (int j = 1; j <= n; j ++) 
				e[i][j] = min(e[i][j], e[i][k] + e[k][j]);
}

int main() {
 	memset(e, 0x3f, sizeof(e));
 	
 	scanf("%d%d\n", &m, &n); 	
 	while (m --) {
 		string s;
 		getline(cin, s);
		s = s + ' ';
		
		int num = 0, cnt = 0;
 		for (int i = 0; i < s.size(); i ++) {
			if (s[i] >= '0' && s[i] <= '9') {
				num = num * 10 + s[i] - '0';
			}
			else {
				a[++ cnt] = num;
				num = 0;
			}
		}
		
 		for (int i = 1; i <= cnt; i ++) {
 			for (int j = i + 1; j <= cnt; j ++) {
 				e[a[i]][a[j]] = 1;
			}
 		}
	}
	
	floyd();
	
	if (e[1][n] == 0x3f3f3f3f) cout << "NO";
	else cout << e[1][n] - 1;
	
	return 0;
}
1378:最短路径(shopth)
  • floyd
#include <bits/stdc++.h>
using namespace std;

int n, v0, e[100][100];

void floyd() {
	for (int k = 1; k <= n; k ++) 
		for (int i = 1; i <= n; i ++) 
			for (int j = 1; j <= n; j ++) 
				e[i][j] = min(e[i][j], e[i][k] + e[k][j]);
}

int main() {
	cin >> n >> v0;	
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n; j ++) {
			string s;
			cin >> s;
			if (s == "-") {
				e[i][j] = 0x3f3f3f3f;
			}
			else {
				int t = 1;
				if (s[0] == '-') {
					t = -1;
					s = s.erase(0, 1);
				}
				
				int num = 0;
				for (int i = 0; i < s.size(); i ++) {
					num = num * 10 + s[i] - '0';
				}
				
				e[i][j] = num * t;
			}			
		}
	}
	
	floyd();

	for (int i = 1; i <= n; i ++) {
		if (i != v0) {
			printf("(%d -> %d) = %d\n", v0, i, e[v0][i]);
		}
	}

	return 0;
}
  • dijkstra不能处理负权边;
  • 虽然有负权边,但是无负环,所以可以用bellman_ford
#include <bits/stdc++.h>
using namespace std;

const int N = 100;
int n, m, v0;
int dis[N];

struct edge{
	int u, v, w;
}e[10000];

void bellman_ford() {
	memset(dis, 0x3f, sizeof(dis));
	dis[v0] = 0;
	
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= m; j ++) {
			int u = e[j].u, v = e[j].v, w = e[j].w;
			dis[v] = min(dis[v], dis[u] + w);
		}
	}	
}

int main() {
	scanf("%d%d", &n, &v0);
	
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n; j ++) {
			char ch[10];
			scanf("%s", ch);
			if (strlen(ch) == 1 && ch[0] == '-') continue;
			e[++ m] = {i, j, atoi(ch)};
		}
	}

	bellman_ford();
	
	for (int i = 1; i <= n; i ++) {
		if (i != v0) {
			printf("(%d -> %d) = %d\n", v0, i, dis[i]);
		}
	}
	
	return 0;
}
1379:热浪(heatwv)
  • dijkstra
#include <bits/stdc++.h>
using namespace std;

const int N = 3000;
int t, c, ts, te;
int e[N][N];
bool vst[N];

void dijkstra() {
	vst[ts] = true;
	
	for (int i = 1; i < t; i ++) {
		int minn = 0;
		for (int j = 1; j <= t; j ++) {
			if (!vst[j] && e[ts][j] < e[ts][minn]) {
				minn = j;
			}
		}
		vst[minn] = true;
		
		for (int j = 1; j <= t; j ++) {
			if (!vst[j]) {
				e[ts][j] = min(e[ts][j], e[ts][minn] + e[minn][j]);
			}
		}
	}	
}

int main() {
	memset(e, 0x3f, sizeof(e));
	
	cin >> t >> c >> ts >> te;
	while (c --) {
		int u, v, w;
		cin >> u >> v >> w;
		e[u][v] = e[v][u] = w;
	}

	dijkstra();	
	printf("%d\n", e[ts][te]);
	
	return 0;
}
  • bellman_ford
#include <bits/stdc++.h>
using namespace std;

const int N = 3000, M = 14000;
int t, c, ts, te;
int dis[N];

struct edge{
	int u, v, w;
}e[M];

void bellman_ford() {
	memset(dis, 0x3f, sizeof(dis));
	dis[ts] = 0;
	
	for (int i = 1; i <= t; i ++) {
		for (int j = 1; j <= 2 * c; j ++) {
			int u = e[j].u, v = e[j].v, w = e[j].w;
			dis[v] = min(dis[v], dis[u] + w);
		}
	}	
}

int main() {
	scanf("%d%d%d%d", &t, &c, &ts, &te);
	
	for (int i = 1; i <= c; i ++) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		e[2 * i - 1] = {u, v, w};
		e[2 * i] = {v, u, w};
	}

	bellman_ford();
	printf("%d\n", dis[te]);
	
	return 0;
}
1381:城市路(Dijkstra)
  • 用dijkstra需要考虑重边
#include <bits/stdc++.h>
using namespace std;

const int N = 2010;
int n, m, e[N][N];
bool vst[N];

void dijkstra() {
	vst[1] = true;
	
	for (int i = 1; i < n; i ++) {
		int t = 0;
		for (int j = 1; j <= n; j ++) {
			if (!vst[j] && e[1][j] < e[1][t]) t = j;
		}
		vst[t] = true;
		
		for (int j = 1; j <= n; j ++) {
			if (!vst[j]) {
				e[1][j] = min(e[1][j], e[1][t] + e[t][j]);
			}
		}
	}
}

int main() {
	memset(e, 0x3f, sizeof(e));	
	
	cin >> n >> m;
	while (m --) {
		int u, v, w;
		cin >> u >> v >> w;
		e[u][v] = e[v][u] = min(e[u][v], w);
	}

	dijkstra();
	
	if (e[1][n] == 0x3f3f3f3f) puts("-1");
	else printf("%d", e[1][n]);
	
	return 0;
}
  • 用bellman_ford不用考虑重边
#include <bits/stdc++.h>
using namespace std;

const int N = 2010, M = 10010;
int n, m, dis[N];

struct edge{
	int u, v, w;
}e[M * 2];

int bellman_ford() {
	memset(dis, 0x3f, sizeof(dis));
	dis[1] = 0;
	
	for (int i = 1; i < n; i ++) {
		for (int j = 1; j <= 2 * m; j ++) {
			int u = e[j].u, v = e[j].v, w = e[j].w;
			dis[v] = min(dis[v], dis[u] + w);
		}
	}

	if (dis[n] == 0x3f3f3f3f) return -1;
	return dis[n];
} 

int main() {
	scanf("%d%d", &n, &m);
	
	for (int i = 1; i <= m; i ++) {
		int u, v, w;
		cin >> u >> v >> w;
		e[2 * i - 1] = {u, v, w};
		e[2 * i] = {v, u, w};
	}

	int t = bellman_ford();	
	printf("%d", t);
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值