这题昨天没过,今天改来改去还是过不了测试点7,令人头秃,先放着改天再回来改吧,用的是Dijkstra算法顺带看看相同路径长度的路径情况,以次权更新路径。网上我看大家都是结合DFS的,但我觉得我这思路也没毛病啊,啊啊啊
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
#define MaxV 502
#define Inf 99999999
int G[MaxV][MaxV];
int n, cp ,sp, m;
vector<int> vis(MaxV,0), carry(MaxV,0), cback(MaxV,0), val(MaxV,0), path(MaxV, -1), dis(MaxV, Inf);
void Dijkstra(int s){
dis[s] = 0;
for(int k = 0; k <= n; k++){
int min = Inf, u = -1;
for(int i = 0; i <= n; i++){//找到未纳入最短路径的最短点
if(!vis[i] && dis[i] < min){
min = dis[i];
u = i;
}
}
if(u == -1) return;
vis[u] = 1;
for(int v = 0; v <= n; v++){//优化dis数组
if(!vis[v] && G[u][v] != Inf && G[u][v] + dis[u] < dis[v]){
dis[v] = G[u][v] + dis[u];
path[v] = u;
}
else if(G[u][v] + dis[u] == dis[v]){//路径长度相同判断带出bike数是否更小
if(carry[v] == carry[u] + ((cp - cback[u] - val[v]) > 0 ? (cp - cback[u] - val[v]):0)){//带出数相同判断是否带回数更小
if(cback[v] > ((val[v] + cback[u] - cp) > 0 ? (val[v] + cback[u] - cp) : 0)) path[v] = u;
}
else if(carry[v] > carry[u] + ((cp - cback[u] - val[v]) > 0 ? (cp - cback[u] - val[v]):0)){
path[v] = u;
}
}
if(path[v] == u){//若dis被优化,修改carry与cback数组
carry[v] = (carry[u] + ((cp - cback[u] - val[v]) > 0 ? (cp - cback[u] - val[v]):0));
cback[v] = ((val[v] + cback[u] - cp) > 0 ? (val[v] + cback[u] - cp) : 0);
}
}
}
}
int main(){
fill(G[0],G[0] + MaxV * MaxV, Inf);
cin >> cp >> n >> sp >> m;
for(int i = 1; i <= n; i++) cin >> val[i];
for(int i = 0; i < m; i++){
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
G[a][b] = G[b][a] = c;
}
cp /= 2;
val[0] = cp;
Dijkstra(0);
printf("%d ",carry[sp]);//带出bike数
stack<int> si;
int temp = sp;
while(temp){
si.push(temp);
temp = path[temp];
}
printf("0");
while(!si.empty()){
printf("->%d",si.top());
si.pop();
}
printf(" %d",cback[sp]);//带回bike数
}