因为是无向图,所以给边赋值的时候,就直接粘贴了,但是没有改变两个端点了位置,调试了一下午,终于找到问题原因了,可喜可贺,可歌可泣。
其实代码写得清晰明了一些,可以节约大量的时间呀!
版本1
PAT测试点
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=505;
const int INF=1e9+5;
int C,N,D,M; //C为每个站的最大容量,N个站点,D为终点,M条路;
int G[maxn][maxn]; //耗时
int d[maxn]; //耗时最短
bool vis[maxn]={false};
int dot[maxn];
vector<int> pre[maxn];
void Dijkstra(int s){
fill(d,d+maxn,INF);
d[s]=0;
for(int i=0;i<=N;i++){ //n个顶点
int u=-1,Min=INF; //每个中间点使源点能到达的最短路径的顶点
for(int j=0;j<=N;j++){
if(vis[j]==false && d[j] < Min){
u = j;
Min = d[j]; //之前写错了,改半天
}
}
if(u==-1) return;
vis[u]=true;
for(int v=0;v<=N;v++){
if(vis[v]==false && G[u][v]!=INF){
if(G[u][v] + d[u] < d[v]){
d[v]=G[u][v] + d[u];
pre[v].clear();
pre[v].push_back(u); //把u设为前驱节点
}else if(G[u][v] + d[u] == d[v]){
pre[v].push_back(u); //直接加在v的后面,表示还有另一个前驱
}
}
}
}
}
int optN=INF,optT=INF; //最小发送车辆和最小带回车辆
vector<int> path,tempPath;
void DFS(int v) {
if(v==0){
tempPath.push_back(0);
int value=0,temp=0,tempN=0,tempT=0;
dot[0]=C;
for(int i=tempPath.size()-1;i>=0;i--){ //从PBMC出发
int id=tempPath[i];
temp+=dot[id]-C;
if(temp < 0){
tempN += (-temp);
temp=0;
}
}
if(temp > 0) tempT = temp;
if(tempN < optN ){
optT=tempT;
optN=tempN;
path=tempPath;
}else if(tempN == optN && tempT < optT){
optT=tempT;
optN=tempN;
path=tempPath;
}
tempPath.pop_back();
return;
}
tempPath.push_back(v);
for(int j=0;j<pre[v].size();j++){
DFS(pre[v][j]);
}
tempPath.pop_back();
}
int main(){
scanf("%d%d%d%d",&C,&N,&D,&M);
int x,y,cost;
C = C>>1;
fill(G[0],G[0]+maxn*maxn,INF);
for(int i=1;i<=N;i++){
scanf("%d",&dot[i]);
}
for(int i=1;i<=M;i++){
scanf("%d%d%d",&x,&y,&cost);
G[x][y]=cost; //为无向图
G[y][x]=cost;
}
Dijkstra(0);
DFS(D);
printf("%d ",optN);
for(int i=path.size()-1;i>=0;i--){
printf(i==0?"%d":"%d->",path[i]);
}
printf(" %d\n",optT);
return 0;
}
版本2
牛客网测试点
这种题还是很不熟练,做第二遍的时候想到了没有以前流畅,但是没想到还是卡了两个小时。
总结一下错误
1.图的边最开始没有赋初值
2.图是无向图
3.顶点的编号一直到n
4.全局变量放在循环程序中反复执行,导致结果异常。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 505;
const int INF = 0x3f3f3f3f;
int G[maxn][maxn];
vector <int> path, tmp, pre[maxn];
int C[maxn];
int d[maxn];
int c, n, ed, m, S = INF, T = INF;
bool vis[maxn];
void Dijkstra(){
fill(d, d + maxn, INF);
d[0] = 0;
for(int i = 0; i <= n; i++){ //取等号
int u = -1, MIN = INF;
for(int j = 0; j <= n; j++){
if(!vis[j] && d[j] < MIN){
MIN = d[j];
u = j;
}
}
vis[u] = true;
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];
pre[v].clear();
}
if(d[u] + G[u][v] == d[v]){
pre[v].push_back(u);
}
}
}
}
}
void DFS(int u) {
tmp.push_back(u);
if(u == 0){
int send = 0, take = 0, t = 0;
C[0] = c;
for(int i = tmp.size() - 1; i >= 0 ; i--){
int id = tmp[i];
take += C[id] - c;
if(take < 0) send += abs(take), take = 0;
}
if(send < S){
S = send;
T = take;
path = tmp;
}else if(send == S && take < T){
T = take;
path = tmp;
}
}
for(int j = 0; j < pre[u].size(); j++){
int v = pre[u][j];
DFS(v);
}
tmp.pop_back();
}
int main(){
cin >> c >> n >> ed >> m;
c >>= 1;
for(int i = 1; i <= n; i++){
cin >> C[i];
}
fill(G[0],G[0]+maxn*maxn,INF); //初始化
int u, v, x;
for(int i = 0; i < m; i++){
cin >> u >> v >> x;
G[u][v] = x;
G[v][u] = x; //无向图
}
Dijkstra();
DFS(ed);
cout<<S<<" "; //PBM带过去的自行车
for(int i = path.size() - 1; i >= 0; i--){
cout<<path[i];
if(i) cout<<"->";
}
cout<<" "<<T<<endl;
return 0;
}