1018 Public Bike Management (30分)

用贪心的思想,25分,5和7测试点错误,原因如下

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 550;
int c, n, e, m;
int G[maxn][maxn], vis[maxn], d[maxn];
int weight[maxn], w[maxn];
vector<int> path[maxn];

void dijkstra(int e) {
	fill(vis, vis + maxn, 0);
	fill(d, d + maxn, INF);
	d[0] = 0;
	fill(w, w + maxn, 0);
	w[0] = 0;

	for (int k = 0; k < n; k++)
	{
		int u = -1, Min = INF;
		for (int i = 0; i < n; i++) {
			if (!vis[i] && d[i] < Min) {
				u = i;
				Min = d[i];
			}
		}
		if (u == -1) { return; }
		vis[u] = 1;
		for (int v = 0; v < n; v++) {
			if (!vis[v] && G[u][v] != INF) {
				if (d[u] + G[u][v] < d[v]) {
					d[v] = d[u] + G[u][v];
					path[v].clear();
					path[v].push_back(u);
					w[v] = w[u] + weight[v];
				}
				else if (d[u] + G[u][v] == d[v]) {
					int a = w[u] + weight[v], b = w[v];//错误方法,见https://blog.csdn.net/weixin_43116322/article/details/103840390
					if ((b < 0 && a > b && a <= 0) || (b > 0 && a < b)) {//不可以用贪心,因为贪心只考虑v节点之前的,故只能用dfs
						w[v] = w[u] + weight[v];
						path[v].clear();
						path[v].push_back(u);
					}
				}
			}
		}
	}
}

vector<int> ans;
void Print(int e) {
	ans.push_back(e);
	if (e == 0) {
		int l = ans.size();
		for (int i = l - 1; i > 0; i--) {
			cout << ans[i] << "->";
		}
		cout << ans[0] << ' ';
		return;
	}
	Print(path[e][0]);
}

int main() {
	fill(G[0], G[0] + maxn * maxn, INF);
	cin >> c >> n >> e >> m;
	c /= 2;
	for (int i = 1; i <= n; i++) {
		int t;
		cin >> t;
		weight[i] = t - c;
	}
	for (int i = 1; i <= m; i++) {
		int a, b, t;
		cin >> a >> b >> t;
		G[a][b] = G[b][a] = t;
	}
	n++;
	dijkstra(e);
	if (w[e] < 0) {
		cout << (-w[e]) << ' ';
		Print(e);
		cout << '0';
	}
	else {
		cout << "0 ";
		Print(e);
		cout << w[e];
	}
	return 0;
}

正确解答

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 550;
int c, n, e, m;
int G[maxn][maxn], vis[maxn], d[maxn];
int weight[maxn];
vector<int> path[maxn];

void dijkstra(int e) {
	fill(vis, vis + maxn, 0);
	fill(d, d + maxn, INF);
	d[0] = 0;
	for (int k = 0; k < n; k++)
	{
		int u = -1, Min = INF;
		for (int i = 0; i < n; i++) {
			if (!vis[i] && d[i] < Min) {
				u = i;
				Min = d[i];
			}
		}
		if (u == -1) { return; }
		vis[u] = 1;
		for (int v = 0; v < n; v++) {
			if (!vis[v] && G[u][v] != INF) {
				if (d[u] + G[u][v] < d[v]) {
					d[v] = d[u] + G[u][v];
					path[v].clear();
					path[v].push_back(u);
				}
				else if (d[u] + G[u][v] == d[v]) {
					path[v].push_back(u);
				}
			}
		}
	}
}

vector<int> ans, temp;
int ansNeed = INF, ansBack = INF;
void dfs(int e) {//注意!!!每一站多的车辆只能放到后面一站去,而不能补充前面车站中少的数目。否则5、7测试点错误
	temp.push_back(e);
	if (e == 0) {
		int  need = 0, back = 0;
		for (int i = temp.size() - 1; i >= 0; i--) {
			int t = weight[temp[i]];
			if (t >= 0) {//该点数量过多
				back += t;
			}
			else {//该点数量过少
				t = -t;
				if (back < t) {
					need += (t - back);
					back = 0;
				}
				else {
					back -= t;
				}
			}
		}
		if (need < ansNeed) {
			ansNeed = need;
			ansBack = back;
			ans = temp;
		}
		else if (need == ansNeed && back < ansBack) {
			ansBack = back;
			ans = temp;
		}
	}
	for (int i = 0; i < path[e].size(); i++) {
		dfs(path[e][i]);
		temp.pop_back();
	}
}

void Print(int e) {
	int l = ans.size();
	for (int i = l - 1; i > 0; i--) {
		cout << ans[i] << "->";
	}
	cout << ans[0] << ' ';
}

int main() {
	fill(G[0], G[0] + maxn * maxn, INF);
	cin >> c >> n >> e >> m;
	c /= 2;//转化最大值为标准值
	for (int i = 1; i <= n; i++) {
		int t;
		cin >> t;
		weight[i] = t - c;//存储目前数量与标准数量的差
	}
	for (int i = 1; i <= m; i++) {
		int a, b, t;
		cin >> a >> b >> t;
		G[a][b] = G[b][a] = t;
	}
	n++;
	dijkstra(e);
	dfs(e);
	cout << ansNeed << ' ';
	Print(e);
	cout << ansBack;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值