【题解】Paid Roads [SP3953] [Poj3411]

传送门:\(\text{Paid}\) \(\text{Roads}\) \(\text{[SP3953]}\) \(\text{[Poj3411]}\)

【题目描述】

给出一张 \(n\) 个点 \(m\) 条边的有向图。对于每条边 \((x,y)\),如果之前经过 \(z\) 点,那么费用为 \(p\),否则为 \(r\)。求 \(1\) 到 \(n\) 的最小费用。如果无法到达则输出 “ \(\text{impossible}\) ”。

【样例】

样例输入:
4 5
1 2 1 10 10
2 3 1 30 50
3 4 3 80 80
2 1 2 10 10
1 3 2 10 50 样例输出:
110

【数据范围】

\(100 \%:\) \(1 \leqslant n,m \leqslant 10,\) \(0 \leqslant p_i,r_i \leqslant 100\)


【分析】

由于边的费用涉及到了是否经过某个点, 而且\(n\) 较小,因此可以考虑状压。

将每个点 \(i\) 分为 \(2^n-1\) 层,第 \(j\) 层表示当前在第 \(i\) 个点,状态为 \(j\)(二进制第 \(k\) 位为 \(1\) 就表示已经经过了点 \(k\),\(0\) 表示还未经过)的状态,跑一遍 \(\text{dijkstra}\) 或者 \(\text{SPFA}\) 即可。

也可以开一个二维的 \(\text{dis}\) 数组,\(dis[i][j]\) 表示当前在点 \(i\),状态为 \(j\) 的最短路,在最短路算法里面按照 \(j\) 分类更新 \(dis\)。

另外注意一下坑点:每个点可经过多次

个人喜欢把所有的点全部建好,直接跑裸的最短路(就像写网络流那样)。

第二种写法代码就不放了。

【Code】

#include<algorithm>
#include<cstdio>
#include<queue>
#define LL long long
#define Re register int
using namespace std;
const int N=10300,M=2e4+3,inf=2e9;
int n,m,x,y,z,p,r,o,V,ans,dis[N],pan[N],head[N];
struct QWQ{int x,d;inline bool operator<(QWQ O)const{return d>O.d;}};
struct QAQ{int w,to,next;}a[M<<1];priority_queue<QWQ>Q;
inline void add(Re x,Re y,Re z){a[++o].w=z,a[o].to=y,a[o].next=head[x],head[x]=o;}
inline void in(Re &x){
Re f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
inline void dijkstra(Re st){
for(Re i=0;i<=n*V;++i)dis[i]=inf,pan[i]=0;//注意初始化时应扫描到n*V
Q.push((QWQ){st,dis[st]=0});
while(!Q.empty()){
Re x=Q.top().x;Q.pop();
if(pan[x])continue;
pan[x]=1;
for(Re i=head[x],to;i;i=a[i].next)
if(dis[to=a[i].to]>dis[x]+a[i].w)
Q.push((QWQ){to,dis[to]=dis[x]+a[i].w});
}
}
inline int Poi(Re i,Re j){return j+(i-1)*V;}//当前在点i状态为j
int main(){
// freopen("123.txt","r",stdin);
in(n),in(m),V=(1<<n)-1;
while(m--){
in(x),in(y),in(z),in(p),in(r);
for(Re j=0;j<=V;++j)
if(j&(1<<x-1))//如果j中包含了x,由于点可经过多次,所以不必判断y的情况
if(j&(1<<z-1))add(Poi(x,j),Poi(y,j|(1<<y-1)),p);//已经经过了z
else add(Poi(x,j),Poi(y,j|(1<<y-1)),r);//还没有经过z
}
dijkstra(Poi(1,1));ans=inf;//出发点为:只经过了1的状态,当前在点1
for(Re j=0;j<=V;++j)ans=min(ans,dis[Poi(n,j)]);
if(ans==inf)puts("impossible");
else printf("%d\n",ans);
}

【题解】Paid Roads [SP3953] [Poj3411]的更多相关文章

  1. 多次访问节点的DFS POJ 3411 Paid Roads

    POJ 3411 Paid Roads Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6553   Accepted: 24 ...

  2. poj3411 Paid Roads

    思路: 搜索.注意点和边都有可能经过多次. 实现: #include <iostream> #include <cstdio> #include <vector> ...

  3. Paid Roads POJ - 3411

    A network of m roads connects N cities (numbered from 1 to N). There may be more than one road conne ...

  4. poj 3411 Paid Roads(dfs)

    Description A network of m roads connects N cities (numbered to N). There may be more than one road ...

  5. POJ 3411 Paid Roads(DFS)

    题目链接 点和边 都很少,确定一个界限,爆搜即可.判断点到达注意一下,如果之前已经到了,就不用回溯了,如果之前没到过,要回溯. #include <cstring> #include &l ...

  6. POJ 3411 Paid Roads(SPFA || DFS)

    题目链接 题意 : 要从1城市到n城市,求最短路是多少,从a城市到达b城市的路程,如果你到过c城市,则需要走p,否则走r长. 思路 : 因为可以来回走,所以不能用单纯的最短路,可以用二维SPFA,状态 ...

  7. poj 3411 Paid Roads

    题意:有m条路,n座城市,走这些路是要付费的,每条路由两种付费方案,设一条路两端是a,b,如果走完这条路在b点付费的话,应付r,如果走这条路之前在c点付费的话,应付p,求从1端点走到n端点的最小费用. ...

  8. 题解-Codeforces671D Roads in Yusland

    Problem Codeforces-671D 题意概要:给定一棵 \(n\) 点有根树与 \(m\) 条链,链有费用,保证链端点之间为祖先关系,问至少花费多少费用才能覆盖整棵树(\(n-1\) 条边 ...

  9. 题解-CodeForces835F Roads in the Kingdom

    Problem CodeForces-835F 题意:求基环树删去环上任意一边后直径最小值,直径定义为所有点对最近距离的最大值 Solution 首先明确删去环上一点是不会影响树内直径的,所以应当先把 ...

随机推荐

  1. vue学习指南:第十一篇(详细) - Vue的 路由 第一篇 ( router )

    一.路由的配置 路由  vue-router 1. 什么是路由? 路由相当于一个配置对象 路由:就是我们通过不同的url访问不同的内容,通过angular.js 可以实现多视图的单页,现在流行的单页面 ...

  2. 【设计模式】Factory

    前言 这篇博客将包括两种设计模式,一种是工厂模式,一种是抽象工厂模式.不管是哪一种设计模式,本质上在解决的问题是对象创建的问题.工厂,可以是简简单单的一个函数,也可以是一个有具体实现的类,也可以是一个 ...

  3. 强大的 strace 工具

    什么是 strace strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统调用. Strace是一个简单的跟踪系统调用执行的工具.在其最简单的形式中,它可以从开始到结束跟 ...

  4. kerberos&LDAP实现免密码登录搭建

    kerberos && openldap 1.install openldap & kerberos server: yum install db4 db4-utils db4 ...

  5. Everybody Dance Now

    一.摘要 作者提出了一种简单的动作迁移方法,实现了"do as I do":给定一个人跳舞的源视频,作者可以在目标对象表演标准动作的短短几分钟后,将该表演转移到一个新的(业余的)目 ...

  6. JS高阶---定时器相关

    首先看几个问题: [主体] (1)定时器真的时定时执行的吗? 顺序验证: 测试结果: 接下来对上述代码做下修改,增加一个长时间工作的消耗,此时再来验证下定时器运行的精准度 结果如下: (2)定时器回调 ...

  7. react知识点

    http://www.cocoachina.com/webapp/20150721/12692.html http://blog.csdn.net/slandove/article/details/5 ...

  8. 201871010124-王生涛《面向对象程序设计(java)》第十三周学习总结

    项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址>http ...

  9. python27期day19:面向对象

    1.class GirlFriend(object): #定义女朋友类: eyes = 2 #类属性(静态属性),是属于当前类的 #当前类的所有对象,所共有的特征 sex = "女" ...

  10. centos7 扩容

    用 df -h, 看到磁盘满了 (注意:如果是二,或者第三次扩容,下面的参数就不一样) fdisk /dev/sda 但是失败了,显示没有多余的分区 可以看到 有个/dev/sda4 是我在这之前刚刚 ...