[Dijkstra + DFS] PAT 1018 Public Bike Management 笔记

我的代码:有两个测试点错了,我知道错在哪,就是我不可以一下判读要运多少车,但是我觉的是题目自己表述不清楚,下次想改再改吧

#include <iostream>
#include <sstream>
#include <string>
#include <sstream>
#include <cstdio>
#include <stdio.h>
#include <string.h>
#include <vector>
#define maxm 510
#define inf 0x3fffffff
using namespace std;

int cap,n,m,o;
int maps[maxm][maxm];
int dist[maxm]={0};
int weight[maxm]={0};
bool visit[maxm]={false};
vector<int> path[maxm];
vector<int> p,temp;
int minv1=-inf,minv2=inf;
int minvalue=inf;
void BFS(int oo){
    temp.push_back(oo);
    if(oo==0){
        int value=0;
        for(int j=temp.size()-1;j>=0;j--){
            value+=weight[temp[j]];
        }
        value=(temp.size()-1)*cap/2-value;
        if(value>0&&minv1==-inf&&value<minv2){
            minv2=value;p=temp;
        }else if(value<=0&&value>minv1){
            minv1=value;p=temp;
        }

        temp.pop_back();  //记得出栈和返回
        return;
    }
    for(int i=0;i<path[oo].size();i++){
        BFS(path[oo][i]);
    }
    temp.pop_back();
}

int main()
{
    cin>>cap>>n>>o>>m;
    n=n+1;
    fill(maps[0],maps[0]+maxm*maxm,inf);
    fill(dist,dist+maxm,inf);
    for(int i=1;i<n;i++){
        cin>>weight[i];
    }
    for(int i=0;i<m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        maps[a][b]=maps[b][a]=c;
    }
    dist[0]=0;
    for(int i=0;i<n;i++){
        int u=-1,minm=inf;
        for(int j=0;j<n;j++){
            if(visit[j]==false&&dist[j]<minm){
                u=j;minm=dist[j];
            }
        }
        if(u==-1)break;
        visit[u]=true;
        for(int j=0;j<n;j++){
            if(visit[j]==false&&maps[j][u]!=inf){
                if(dist[j]>maps[u][j]+dist[u]){
                    dist[j]=maps[u][j]+dist[u];
                    path[j].clear();
                    path[j].push_back(u);
                }else if(dist[j]==maps[u][j]+dist[u]){
                    path[j].push_back(u);
                }
            }
        }
    }
    BFS(o);
    int a,b;
    if(minv1==-inf&&minv2!=inf){
        a=minv2;b=0;
    }else if(minv1!=-inf){
        a=0;b=-minv1;
    }
    cout<<a<<" ";
    for(int i=p.size()-1;i>0;i--){  //逆序输出
        cout<<p[i]<<"->";
    }
    cout<<p[0]<<" "<<b;
    return 0;
}

柳神代码:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int inf = 99999999;
int cmax, n, sp, m;
int minNeed = inf, minBack = inf;
int e[510][510], dis[510], weight[510];
bool visit[510];
vector<int> pre[510], path, temppath;
void dfs(int v) {
    temppath.push_back(v);
    if(v == 0) {
        int need = 0, back = 0;
        for(int i = temppath.size() - 1; i >= 0; i--) {
            int id = temppath[i];
            if(weight[id] > 0) {
                back += weight[id];
            } else {
                if(back > (0 - weight[id])) {
                    back += weight[id];
                } else {
                    need += ((0 - weight[id]) - back);
                    back = 0;
                }
            }
        }
        if(need < minNeed) {
            minNeed = need;
            minBack = back;
            path = temppath;
        } else if(need == minNeed && back < minBack) {
            minBack = back;
            path = temppath;
        }
        temppath.pop_back();
        return ;
    }
    for(int i = 0; i < pre[v].size(); i++)
        dfs(pre[v][i]);
    temppath.pop_back();
}
int main() {
    fill(e[0], e[0] + 510 * 510, inf);
    fill(dis, dis + 510, inf);
    scanf("%d%d%d%d", &cmax, &n, &sp, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &weight[i]);
        weight[i] = weight[i] - cmax / 2;
    }
    for(int i = 0; i < m; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        scanf("%d", &e[a][b]);
        e[b][a] = e[a][b];
    }
    dis[0] = 0;
    for(int i = 0; i <= n; i++) {
        int u = -1, minn = inf;
        for(int j = 0; j <= n; j++) {
            if(visit[j] == false && dis[j] < minn) {
                u = j;
                minn = dis[j];
            }
        }
        if(u == -1) break;
        visit[u] = true;
        for(int v = 0; v <= n; v++) {
            if(visit[v] == false && e[u][v] != inf) {
                if(dis[v] > dis[u] + e[u][v]) {
                    dis[v] = dis[u] + e[u][v];
                    pre[v].clear();
                    pre[v].push_back(u);
                }else if(dis[v] == dis[u] + e[u][v]) {
                    pre[v].push_back(u);
                }
            }
        }
    }
    dfs(sp);
    printf("%d 0", minNeed);
    for(int i = path.size() - 2; i >= 0; i--)
        printf("->%d", path[i]);
    printf(" %d", minBack);
    return 0;
}

dfs里要模拟运车的过程才是正确的(因为返程不会调整车!!!),不能一下判断要运多少车

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值