我的做法:
#include <iostream>
#include <string>
#include<sstream>
using namespace std;
int bikeNumInStation[501];// 站台此时此刻的自行车数量
int matrix[501][501];// 邻接矩阵
int path[501];// 记录最短路径
int visited[501];// 记录结点是否被访问过
const int MAXINT=0x7fffffff;
int send[501];// 记录到i顶点时需要从总部借出车辆
int collect[501];// 记录到i顶点时收集的车辆总数
string formatPath[501];// 记录到i顶点所经过的顶点情况
int main(int argc, char** argv) {
int capacity;// 站台的容量
int n;// 站台数
int wrongStation;// 需要修复的站台
int m;// 路的数量
cin>>capacity>>n>>wrongStation>>m;
int perfect=capacity/2;
for(int i=1;i<=n;i++){
cin>>bikeNumInStation[i];
}
// 初始化邻接矩阵
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
if(i!=j) matrix[i][j]=MAXINT;
}
}
for(int i=0;i<m;i++){
int row,col,weight;
cin>>row>>col>>weight;
matrix[row][col]=weight;
matrix[col][row]=weight;
}
// 迪杰斯特拉算法找单源最短路径
// 初始化path数组
for(int i=1;i<=n;i++){
path[i]=MAXINT;
}
// 初始化formatPath数组
for(int i=0;i<=n;i++){
formatPath[i]="0";
}
for(int i=0;i<=n;i++){
// 找到path中最短的那条
int shortestPath=MAXINT,shortestNode=-1;
for(int j=0;j<=n;j++){
if(visited[j]==0&&path[j]<shortestPath){
shortestPath=path[j];
shortestNode=j;
}
}
// 确定该节点被访问过
visited[shortestNode]=1;
// cout<<"第"<<i<<"次确定最短路径的结点为"<<shortestNode<<endl;
// 更新path路径
for(int j=0;j<=n;j++){
// 该顶点没有确定出最短路径 且 从shortestNode到该顶点有路径
if(visited[j]==0&&matrix[shortestNode][j]!=MAXINT){
if(matrix[shortestNode][j]+shortestPath>path[j]) continue;
else if(matrix[shortestNode][j]+shortestPath<path[j]){
// 经过shortestNode到达该顶点的路径更短
path[j]=matrix[shortestNode][j]+shortestPath;
// 计算经过shortestNode时最短路径的send和collect
int sendj=send[shortestNode],collectj=collect[shortestNode];
if(bikeNumInStation[j]<perfect){
if(collect[shortestNode]>=perfect-bikeNumInStation[j])
collectj-=perfect-bikeNumInStation[j];
else{
sendj+=perfect-bikeNumInStation[j]-collect[shortestNode];
collectj=0;
}
}else if(bikeNumInStation[j]>perfect){
collectj+=bikeNumInStation[j]-perfect;
}
// 设置新值
send[j]=sendj;
collect[j]=collectj;
formatPath[j]=formatPath[shortestNode]+"->"+to_string(j);
}else{
// 找到一条路径长度相同的路径时
// 计算经过shortestNode时最短路径的send和collect
int sendj=send[shortestNode],collectj=collect[shortestNode];
if(bikeNumInStation[j]<perfect){
if(collect[shortestNode]>=perfect-bikeNumInStation[j])
collectj-=perfect-bikeNumInStation[j];
else{
sendj+=perfect-bikeNumInStation[j]-collect[shortestNode];
collectj=0;
}
}else if(bikeNumInStation[j]>perfect){
collectj+=bikeNumInStation[j]-perfect;
}
// 比较取send更少,collect更小的情况
if(sendj<send[j]||(sendj==send[j]&&collectj<collect[j])){
send[j]=sendj;
collect[j]=collectj;
formatPath[j]=formatPath[shortestNode]+"->"+to_string(j);
}
}
}
}
// cout<<"更新后的path:";
// for(int j=0;j<=n;j++){
// cout<<path[j]<<" ";
// }
// cout<<endl;
// cout<<"更新后的send:";
// for(int j=0;j<=n;j++){
// cout<<send[j]<<" ";
// }
// cout<<endl;
// cout<<"更新后的collect:";
// for(int j=0;j<=n;j++){
// cout<<collect[j]<<" ";
// }
// cout<<endl;
}
cout<<send[wrongStation]<<" "<<formatPath[wrongStation]<<" "<<collect[wrongStation];
return 0;
}
测试点7会过不了,因为我使用了贪心算法,但实际上并不符合贪心算法,原因如下:
图片内容来源:包含正解