思路就是dijkstra找出最短路,dfs比较每一个最短路。

dijkstra可以找出每个点的前一个点, 所以dfs搜索比较的时候怎么处理携带和带走的数量就是关键,考虑到这个携带和带走和路径顺序有关,所以可以用下面的写法,看代码就可以了。

最开始的时候是想用一个偏动态规划的写法做,但是因为题目的显示,既要带去的车数量最少,又要求从一个点带走的车数量最少,所以如果过动规的话,对于一个点的多个最短路,就会选择带去数量最少,带走车数最少的路径,但是如果这个点后面的点的车辆数少一标准量的一半的话,前面带的是最少的,这样相当于携带的车的数量就多了,这样就矛盾了。

当时挺纠结的,因为只写过一道类型的题,还是用动规的写法写的,那个权值只有两个,也是pat的题,这个主要是权值矛盾了, 所以不能用动规的思想写。

#include <bits/stdc++.h>
using namespace std;
const int maxn=505;
const int INF=0x3f3f3f3f; int g[maxn][maxn];
vector<int> pre[maxn];
int C,N,M,SP;
int vis[maxn],num[maxn],d[maxn]; void dijkstra()
{
d[0]=0; for (int i=0;i<N;i++) {
int u=-1,tmp=INF;
for (int j=0;j<=N;j++) {
if (!vis[j]&&d[j]<tmp) {
tmp=d[j];
u=j;
}
}
if (u==-1) break;
vis[u]=1;
for (int j=0;j<=N;j++) {
if (j==u) {
continue;
}
if (d[u]+g[u][j]<d[j]) {
d[j]=d[u]+g[u][j];
pre[j].clear();
pre[j].push_back(u);
}
else if (d[u]+g[u][j]==d[j]) {
pre[j].push_back(u);
}
}
}
} int path[maxn],acnt=0;
int ansn=INF,anst=INF,ansp[maxn];
void dfs(int u,int need,int take,int cnt)
{
path[cnt]=u;
if (u==0) {
// for (int i=0;i<cnt;i++) {
// printf("%d ",path[i]);
// }
// puts("");
// printf("need %d take %d\n",need,take);
if (need<ansn) {
ansn=need;
anst=take;
acnt=cnt;
for (int i=0;i<cnt;i++) {
ansp[i]=path[i];
} }
else if (need==ansn) {
if (take<anst) {
anst=take;
acnt=cnt;
for (int i=0;i<cnt;i++) {
ansp[i]=path[i];
}
}
}
return ;
}
if (num[u]==C/2) {}
else if (num[u]>C/2) {
if (need>0) {
if (num[u]-C/2>=need) {
take+=num[u]-C/2-need;
need=0;
}
else need-=num[u]-C/2;
}
else take+=num[u]-C/2;
}
else need+=C/2-num[u]; int sz=pre[u].size();
for (int i=0;i<sz;i++) { dfs(pre[u][i],need,take,cnt+1);
}
} int main()
{
// freopen("in.txt","r",stdin);
scanf("%d%d%d%d",&C,&N,&SP,&M);
for (int i=1;i<=N;i++) {
scanf("%d",&num[i]);
} memset(g,INF,sizeof(g));
for (int i=0;i<=N;i++) {
g[i][i]=0;
d[i]=INF;
} int u,v,c;
for (int i=0;i<M;i++) {
scanf("%d%d%d",&u,&v,&c);
g[u][v]=c;
g[v][u]=c;
}
dijkstra();
// for (int i=1;i<=N;i++) {
// printf("%d ",d[i]);
// }
// puts("");
// for (int i=1;i<=N;i++) {
// printf("%d:\n",i);
// for (int j=0;j<pre[i].size();j++) {
// printf("%d ",pre[i][j]);
// }
// printf("\n");
// }
dfs(SP,0,0,0);
printf("%d %d",ansn,0);
for (int i=acnt-1;i>=0;i--) {
printf("->%d",ansp[i]);
}
printf(" %d\n",anst);
return 0;
}

1018 Public Bike Management (30分) (迪杰斯特拉+dfs)的更多相关文章

  1. PAT 甲级 1018 Public Bike Management (30 分)(dijstra+dfs,dfs记录路径,做了两天)

    1018 Public Bike Management (30 分)   There is a public bike service in Hangzhou City which provides ...

  2. 1018 Public Bike Management (30 分)

    There is a public bike service in Hangzhou City which provides great convenience to the tourists fro ...

  3. 1018 Public Bike Management (30分) 思路分析 + 满分代码

    题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...

  4. 1018 Public Bike Management (30分) PAT甲级真题 dijkstra + dfs

    前言: 本题是我在浏览了柳神的代码后,记下的一次半转载式笔记,不经感叹柳神的强大orz,这里给出柳神的题解地址:https://blog.csdn.net/liuchuo/article/detail ...

  5. 【PAT甲级】1018 Public Bike Management (30 分)(SPFA,DFS)

    题意: 输入四个正整数C,N,S,M(c<=100,n<=500),分别表示每个自行车站的最大容量,车站个数,此次行动的终点站以及接下来的M行输入即通路.接下来输入一行N个正整数表示每个自 ...

  6. 1018 Public Bike Management (30)(30 分)

    时间限制400 ms 内存限制65536 kB 代码长度限制16000 B There is a public bike service in Hangzhou City which provides ...

  7. 1018. Public Bike Management (30)

    时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue There is a public bike service i ...

  8. PAT Advanced 1018 Public Bike Management (30) [Dijkstra算法 + DFS]

    题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...

  9. 1018 Public Bike Management (30) Dijkstra算法 + DFS

    题目及题解 https://blog.csdn.net/CV_Jason/article/details/81385228 迪杰斯特拉重新认识 两个核心的存储结构: int dis[n]: //记录每 ...

随机推荐

  1. vue项目出现Module not found: Error: Can't resolve 'stylus-loader'错误解决方案

    因为没有安装stylus和stylus-loader npm install stylus stylus-loader --save-dev 安装成功后,使用npm install重新建立依赖 打开项 ...

  2. AcWing 891. Nim游戏

    //a1 ^ a2 ^ ··· ^ an = 0 –>先手必败: //a1 ^ a2 ^ ··· ^ an != 0 –>先手必胜: #include<iostream> us ...

  3. PHP程序员应该如何提升

    PHP程序员应该如何提升 尤其不认可W3school之类的东西,不够深度,理解不深,比起这个更建议看官方文档,中文不清楚,看英文的. 入门视频:入门视频推荐:哈佛大学公开课:构建动态网站Beginne ...

  4. dmesg用法

    百科概念:dmesg是一种程序,用于检测和控制内核环缓冲.程序用来帮助用户了解系统的启动信息. 解释:dmesg命令显示linux内核的环形缓冲区信息,我们可以从中获得诸如系统架构.cpu.挂载的硬件 ...

  5. Hibernate项目的基本步骤和一些错误提示

    以数据库中有一张user表为例: 1.编写POJO持久化类User.javaPOJO(Plain Old Java Objects),简单的Java对象.一个POJO类不用继承任何类,也无须实现任何接 ...

  6. 关于Win32串口

    因为近段时间接触Hid相对来说多一些,由此忽略了串口中获取cbInQue这个重要的东西,下面是错误代码 // Win32SerialPortLib.cpp : 定义 DLL 应用程序的导出函数. // ...

  7. java基础之 类型转换

    一.自动类型转换 1.java中不同类型的数据在计算时,为保证数据的精度,数据的类型会以大容量的类型为主: 2.自动类型转换的排序: char.byte.short -> int -> l ...

  8. C++-POJ1988-Cube Stacking[数据结构][并查集]

    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} #include <set> #include <map> #inc ...

  9. 【译】通过 Rust 学习解析器组合器 — Part 1

    原文地址:Learning Parser Combinators With Rust 原文作者:Bodil 译文出自:掘金翻译计划 本文永久链接:https://github.com/xitu/gol ...

  10. ffmpeg 音频常用命令

    ffmpeg的使用方式: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... Stream ...