POJ 3411 DFS
大致题意:
有n座城市和m(1<=n,m<=10)条路。现在要从城市1到城市n。有些路是要收费的,从a城市到b城市,如果之前到过c城市,那么只要付P的钱,如果没有去过就付R的钱。求的是最少要花多少钱。
注意:路径是有向的。
解题思路:
DFS。这题当有了思路后,做起来是没有难度的,但是思维推算能力要求很高。
这题难点在于“城市与城市之间可能存在多条路径”:
1、 输入数据时可能会出现多条 从城市a到城市b的路径信息,但是费用有所差别;
2、 对于 从城市a到城市b 的同一条路径,允许重复走。
有人会问,重复走同一条路径有什么意义?单纯增加费用而已,为什么不能标记所有路径,每条路只允许走一次,这样费用不是更少么?
我开始也是陷入了这种思维,但是这种想法其实“对一半,错一半”。
先来看一组数据:
6 5
1 2 1 10 10
2 3 4 10 100
2 4 2 15 15
4 1 1 12 12
3 6 6 10 10
如果每条路只允许走一次,那么方案只有1个:
1à2à3à6 共135元
但这组数据的正确答案是67元。为什么?正确的方案如下:
1à2à4à1à2à3à6 共67元
显然1à2重复走了一次,目的是为了先到达城市4,从而使得2à3这段路的费用从100缩减到10元。
转载自:優YoU http://blog.csdn.net/lyy289065406/article/details/6689310
因为就10个点,100条边。
考虑DFS
我们考虑有没有环路的时候不一定非要标记一个点被访问了多少次。
(个人认为这样并不科学)
小優YoU(这应该叫前辈了吧)说:
那么应该重复多少次才合理?这与m值有关。题目的m值范围为<=10,那么当人一个城市被到达的次数若 >3次(不包括3),所走的方案必然出现了环路(网上的同学称之为“闸数”)。因此只需把bool vist[] 修改为 int vist[] 进行标记,本题就能解决了。
但是并没有说出为什么一个点被访问3次就不能更优了,,
所以我认为这是数据水,卡过去的。。
我是把所有的vis设成m,每个点m次,,肯定所有的最优环都包括了。
加个剪枝:if(cost>ans)return;
也是0ms。。。。。
// by SiriusRen
#include <cstdio>
using namespace std;
int n,m,xx,yy,p,r,ans=0x3fffffff,vis[105],P[105],R[105];
int first[15],next[105],v[105],C[105],VIS[105];
void dfs(int x,int cost){
VIS[x]++;
if(cost>ans)return;
if(x==n&&ans>cost)ans=cost;
for(int i=first[x];i;i=next[i])
if(VIS[v[i]]<=m){
if(VIS[C[i]])dfs(v[i],cost+P[i]);
else dfs(v[i],cost+R[i]);
VIS[v[i]]--;
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d%d%d",&p,&v[i],&C[i],&P[i],&R[i]);
next[i]=first[p],first[p]=i;
}
VIS[1]=1,dfs(1,0);
if(ans!=0x3fffffff)printf("%d\n",ans);
else puts("impossible");
}
但是还有几个版本莫名其妙AC,,,
1.
统计每个边经过的次数,次数小于等于2。
0msAC
// by SiriusRen
#include <cstdio>
using namespace std;
int n,m,xx,yy,p,r,ans=0x3fffffff,vis[105],P[105],R[105];
int first[15],next[105],v[105],C[105],VIS[105];
void dfs(int x,int cost){
if(x==n&&ans>cost)ans=cost;
for(int i=first[x];i;i=next[i])
if(vis[i]<=1){
vis[i]++,VIS[v[i]]++;
if(VIS[C[i]])dfs(v[i],cost+P[i]);
else dfs(v[i],cost+R[i]);
vis[i]--,VIS[v[i]]--;
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d%d%d",&p,&v[i],&C[i],&P[i],&R[i]);
next[i]=first[p],first[p]=i;
}
VIS[1]=1,dfs(1,0);
if(ans!=0x3fffffff)printf("%d\n",ans);
else puts("impossible");
}
2.统计每个点经过的次数。
次数小于等于3. 这里就不放代码了。。。 网上一抓一大把
乱做实验的后果,,,
POJ 3411 DFS的更多相关文章
- 多次访问节点的DFS POJ 3411 Paid Roads
POJ 3411 Paid Roads Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6553 Accepted: 24 ...
- poj 3411 Paid Roads很水的DFS
题意:给你N 城市和M条道路,每条道路要付的钱,但是如果你在这个道路上你可以付其他道路的钱(跟走到的时候去的话不一样),问你从1走到N最少话费是多少. 直接DFS搜. 链接http://poj.org ...
- POJ 3411 Paid Roads(DFS)
题目链接 点和边 都很少,确定一个界限,爆搜即可.判断点到达注意一下,如果之前已经到了,就不用回溯了,如果之前没到过,要回溯. #include <cstring> #include &l ...
- POJ 3411 Paid Roads(SPFA || DFS)
题目链接 题意 : 要从1城市到n城市,求最短路是多少,从a城市到达b城市的路程,如果你到过c城市,则需要走p,否则走r长. 思路 : 因为可以来回走,所以不能用单纯的最短路,可以用二维SPFA,状态 ...
- poj 3411 Paid Roads(dfs)
Description A network of m roads connects N cities (numbered to N). There may be more than one road ...
- 广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告
题目链接:http://poj.org/problem?id=3411 题目意思:N个city 由 m 条路连接,对于一条路(假设连接Cityia和 Cityb),如果从Citya 去 Cityb的途 ...
- POJ 1321 DFS
题意:POJ少见的中文题,福利啊. 思路: 一开始也没有思路呃呃呃 . 裸搜,连样例都过不去...参照了网上的题解:一行一行DFS 茅塞顿开啊. #include <cstdio> #in ...
- POJ 1979 dfs和bfs两种解法
fengyun@fengyun-server:~/learn/acm/poj$ cat 1979.cpp #include<cstdio> #include<iostream&g ...
- poj 1190 DFS 不等式放缩进行剪枝
F - (例题)不等式放缩 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submi ...
随机推荐
- 【Oracle】创建概要文件
任务1:创建profile 创建概要文件my_profile 1)密码复杂性要求:启用: 2)密码长度最小值:8位: 3)密码错误输入三次,锁定账户,2分钟后自动解锁 --创建密码复杂度校验函数 @? ...
- 微信App支付:微信支付的appid,appsecret,商户号mch_id,微信交易支付密钥(mch_key)在哪里查看
1-1) 查看微信支付 appid 的方法 微信支付使用的 appid, 是微信服务号的 appid, 需要你登录微信服务号后台, 在 开发-基本配置/开发者ID(AppID) 中查看微信支付 app ...
- Oracle下rman备份和还原到数据库任意一个时间点
Rman备份为物理备份,启用rman备份必须开启数据库归档,开启归档后相当于给数据库加了一层双保险.Rman备份主要备份数据库的数据文件,控制文件,归档日志. RMAN 备份 一. 检查数据库是否启用 ...
- vc++如何创建程序--利用快捷键进行多行注释
Eclipse同时注释多行①:ctrl+/或 ②:ctrl+shift+/ : Visual studio先按ctrl+k 再按 ctrl+c 2.在VC++6.0中需要自己设置快捷键,设置方法链接如 ...
- 快速搭建一个本地的FTP服务器 win10及win7
快速搭建一个本地的FTP服务器 如果需要开发FTP文件上传下载功能,那么需要在本机上搭建一个本地FTP服务器,方便调试. (win10) 第一步:配置IIS Web服务器 1.1 控制面板中找到“ ...
- 何为JQuery对象?
- Python笔记16-------类
1.类的定义 (1)#括号中要加入父类,如果没有则默认为object,万类之源 class 类名(父类): '类的文档字符串' 类体代码 若类什么都不做,则类只作为命名空间,仅作为一个容器. (2)类 ...
- URL编码及解码
为什么要对URL进行编码? 一般来说,网页URL只能使用英文.数字.还有一些特定的字符.根据网络标准RFC 1738做了硬性规定: 只有字母和数字[0-9a-zA-Z].一些特殊符号"$-_ ...
- [USACO17JAN] Promotion Counting晋升者计数 (树状数组+dfs)
题目大意:给你一棵树,求以某节点为根的子树中,权值大于该节点权值的节点数 本题考查dfs的性质 离散+树状数组求逆序对 先离散 我们发现,求逆序对时,某节点的兄弟节点会干扰答案 所以,我们在递推时统计 ...
- CentOS 笔记(六) 历史命令 自动补充
history #出现历史的命令 #执行具体的一条历史命令 !458 ②安装自动补充功能 yum install -y bash-completion #输入命令 按Tab 会显示所有内容 syste ...