A1018 Public Bike Management (30 分)

1018 Public Bike Management (30 分)

解题思路

       最短路径问题,除了要求路径最短之外还增加了额外的两个维度,同样最短的路径要求从管理站带去的自行车的量数最小,带去的量数相同时要求带回管理站的自行车的量数最小。解题的思路是Dijstra+DFS。这是解决此类问题的通用套路。
       在做这道题的时候我犯了一个非常严重的逻辑错误,导致耽搁了很长时间。设带回去的最小车辆数为mint,需要带去的最小车辆数为minb,一条最短路径需要带去和带回的车辆数分别为bt。那么什么时候需要更新mint呢?当已知一条路径的b等于minb的时候,而我却是在b == minb && t < mint的时候更新,现在想想真是非常低级的错误。犯这个错误部分也是因为我一开始读题不仔细,漏掉了当b == minb的时候还需要选择t == mint的线路。

AC代码

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 502;
const int INF = 0x7ffffff;
struct node {
	int id;
	int t;
	node(){}
	node(int _id, int _t): id(_id), t(_t) {}
};
int c, n, m, sp, d[maxn];
vector<int> cap, pre[maxn], path, tempPath;
vector<node> adj[maxn];
bool vis[maxn] = {false};
void dijstra() {
    fill(d, d + maxn, INF);
	d[0] = 0;
    for (int i = 0; i <= n; ++i) {
    	int u = -1, min_d = INF;
    	for (int j = 0; j <= n; ++j) {
    		if (vis[j] == false && d[j] < min_d) {
    			min_d = d[j];
    			u = j;
    		}
    	}
    	if (u == -1) return;
    	vis[u] = true;
    	for (int i = 0; i < adj[u].size(); ++i) {
    		int v = adj[u][i].id;
            if (vis[v] == false) {
                if (d[u] + adj[u][i].t < d[v]) {
                    d[v] = d[u] + adj[u][i].t;
                    pre[v].clear();
                    pre[v].push_back(u);
                }
                else if (d[u] + adj[u][i].t == d[v]) {
                    pre[v].push_back(u);
                }
            }
    	}
    }
}
int t, b, minb = INF, mint = INF; // t是带回,b是带去
void DFS(int s) {
    if (s == 0) {
    	tempPath.push_back(s);
        t = 0, b = 0;
    	for (int i = tempPath.size() - 2; i >= 0; --i) {
    		int v = cap[tempPath[i]] - c/2;
    		if (v >= 0) {
    			t += v;
    		} else {
    			if (t >= -v)
    				t += v;
    			else {
                    b -= v + t;
                    t = 0;
                }
    		}
    	}
    	if (b < minb) { // 此时需要更新mint
    		minb = b;
            mint = t;
    		path = tempPath;
    	} else if (b == minb && t < mint) {
            mint = t;
            path = tempPath;
        }
    	tempPath.pop_back();
    }
    tempPath.push_back(s);
    for (int i = 0; i < pre[s].size(); ++i) {
    	DFS(pre[s][i]);
    }
    tempPath.pop_back();
}

int main() {
	scanf("%d%d%d%d", &c, &n, &sp, &m);
	cap.resize(n + 1);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &cap[i]);
	}
	for (int i = 0; i < m; ++i) {
		int a, b, time;
		scanf("%d %d %d", &a, &b, &time);
        adj[a].push_back(node(b, time));
        adj[b].push_back(node(a, time));
	}
	dijstra();
	DFS(sp);
	printf("%d ", minb);
	for (int i = path.size() - 1; i >= 0; --i) {
		printf("%d%s", path[i], i != 0? "->" : " ");
	}
	printf("%d\n", mint);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/LinxRds/article/details/89439358
今日推荐