1018 Public Bike Management (30 分)

Keywords: dfs+dij 总感觉能直接dij

There is a public bike service in Hangzhou City which provides great convenience to the tourists from all over the world. One may rent a bike at any station and return it to any other stations in the city.
The Public Bike Management Center (PBMC) keeps monitoring the real-time capacity of all the stations. A station is said to be in perfect condition if it is exactly half-full. If a station is full or empty, PBMC will collect or send bikes to adjust the condition of that station to perfect. And more, all the stations on the way will be adjusted as well.
When a problem station is reported, PBMC will always choose the shortest path to reach that station. If there are more than one shortest path, the one that requires the least number of bikes sent from PBMC will be chosen.

在这里插入图片描述

在这里插入图片描述

Sample Input:

10 3 3 5
6 7 0
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1

Sample Output:

3 0->2->3 0

Note

  1. 题目理解有误,或者说考率的情况不全,没有考虑到在非搬运目的地需要车子的情况
  2. 题意: 具体阅读技巧在ie笔记里在这里插入图片描述

code1

#include<iostream>
#include<algorithm>
#include<fstream>
#include<vector> 
using namespace std;
const int MAX = 1e4 + 10;
int a[MAX][MAX], dis[MAX], visited[MAX] = {0}, path[MAX], num, max_load, bikes[MAX], sum[MAX] = {0};
int got_in_road[MAX] = {0};// 记录途中节点可以提供的车子数目
void Dijkstra(void){
    while(1){
        int min = MAX, ptr = 0;
        for(int i = 0; i <= num; i++){
            if(visited[i] == 0 && dis[i] < min){
                min = dis[i];
                ptr = i;
            }
        }
        if(min == MAX) break;
        visited[ptr] = 1;
        for(int i = 0; i <= num; i++){
            if(visited[i] == 0 && dis[i] > dis[ptr] + a[ptr][i]){
                dis[i] = dis[ptr] + a[ptr][i];
                path[i] = ptr;
				got_in_road[i] += got_in_road[ptr];
            }
            else if(visited[i] == 0 && dis[i] == dis[ptr] + a[ptr][i]){                  //若同为最短路,选择途中能够提供更多车子的一条
                if(got_in_road[i] < bikes[i] - max_load / 2 + got_in_road[ptr]){
					got_in_road[i] = bikes[i] - max_load / 2 + got_in_road[ptr]; 
                    path[i]  = ptr;  
                }
            }
        }
    }
}
int main(){   
#ifdef _DEBUG
    ifstream cin("data.txt");
#endif
    int edge, check;
    cin >> max_load >> num >> check >> edge;
	for(int i = 0; i <= num; i++){
		for(int j = 0; j <= num; j++){
			a[i][j] = MAX;
		}
		dis[i] = MAX;
	}
    for(int i = 1; i <= num; i++){
        cin >> bikes[i];
		got_in_road[i] = bikes[i] - max_load / 2;
    }
    for(int i = 0; i < edge; i++){
        int tempa, tempb, tempc;
        cin >> tempa >> tempb >> tempc;
        a[tempa][tempb] = tempc;
        a[tempb][tempa] = tempc;
    }
	for(int i = 1; i <= num; i++){
		if(a[0][i] < MAX){
			dis[i] = a[0][i];
		}
	}
    path[0] = -1;
    sum[0] = 0;
	visited[0] = 1;
    Dijkstra();
    int cnt = 0,temp = check;
    vector < int > save;
    while(1){ 
        cnt++;
        save.push_back(temp);
        temp =path[temp];
		if(temp == -1) break;
    }
	int sendback = 0;
	if(got_in_road[check]  >  0 ){ sendback = got_in_road[check] ;  got_in_road[check] = 0;}
    cout << -got_in_road[check] << " ";
    temp = check;
    for(int i = save.size() - 1; i > 0; i--){ 
        cout << save[i] << "->";
        temp =path[temp];
    }
 
 
    cout << save[0] << " " <<sendback;
#ifdef _DEBUG
    cin.close();
#endif
    return 0;
}

Note2

  1. 看完算法笔记,确定思路 -> 手写整体框架 -> 手写用到的变量 -> 调bug
  2. 整体思路感觉应该就是这样,具体要注意for循环的边际和初始化的地方和重点思路的逻辑部分
  3. 还有待总结不能直接使用dij解决最短路的问题

Code

#include<iostream>
#include<fstream>
#include<algorithm>
#include<vector>
using namespace std;
const int MAX  =  1e3 + 10;
vector <int> path[MAX], real_path, temp_path;
int need = 0, return_back = 0,  num, check, weight[MAX], collected[MAX] = {0}, disitance[MAX], a[MAX][MAX]; 
int min_return_back = MAX, min_need = MAX;
void Dijkstra(int start){
	collected[start] = 1;
	while(1){
		int min = MAX, ptr = 0;
		for(int i = 1; i <= num; i++){
			if(collected[i] == 0 && disitance[i] < min){
				ptr = i;
				min = disitance[i];
			}
		}
		if(min ==	MAX)	break;
		collected[ptr] = 1;
		for(int i = 1; i <= num; i++){
			if(a[ptr][i] + disitance[ptr] < disitance[i] && collected[i] == 0){
				disitance[i] = disitance[ptr] + a[ptr][i];
				path[i].clear();
				path[i].push_back(ptr);
			}
			else if(a[ptr][i] + disitance[ptr] == disitance[i] && collected[i] == 0){
				path[i].push_back(ptr);
			}
		}
	}
}
void Dfs(int n){
	temp_path.push_back(n);
	if(n == 0){
		need = return_back = 0;
		for(int i = temp_path.size() - 2; i >= 0; i--){
			int id = temp_path[i];
			if(weight[id] > 0)
				return_back += weight[id];
			else {
				if(return_back > - weight[id]) return_back += weight[id];
				else {
					need += -weight[id] - return_back;
					return_back = 0; 		
				}
			}
		}
		if(need < min_need){
			real_path = temp_path;
			min_need = need;
		}
		if(need == min_need && return_back < min_return_back){
			real_path = temp_path;
			min_return_back = return_back;			
		}
	}
	for(int i = path[n].size() - 1; i >= 0; i--){
		Dfs(path[n][i]);
	}
	temp_path.pop_back();
}
int main(){
	int max_load, edge;
#ifdef _DEBUG
	ifstream cin("data.txt");
#endif
	cin >> max_load >> num >> check  >> edge ;
	fill(a[0], a[0] + (num  + 1) * MAX, MAX);
	fill(disitance, disitance + num + 1, MAX);
	for(int i = 1; i <= num; i++){
		cin >> weight[i];
		weight[i] -= max_load / 2;
	}
	for(int i = 0; i < edge; i++){
		int tempa, tempb, tempc;
		cin >> tempa >> tempb >> tempc;
		a[tempa][tempb] = tempc;
		a[tempb][tempa] = tempc;
	}
	for(int i = 1; i <= num; i++){
		if(a[0][i] <	MAX){
			disitance[i] = a[0][i];
			path[i].push_back(0);
		}
	}
	Dijkstra(0);
	Dfs(check);
	cout << min_need << " " << 0 << "->";
	for(int i = real_path.size() - 2; i > 0; i--){
		cout << real_path[i] << "->";
	}
	cout << real_path[0] << " "<<min_return_back;
#ifdef _DEBUG
	cin.close();
#endif
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值