题意:

快递到了:你是某个岛国(ACM-ICPC Japan)上的一个苦逼程序员,你有一个当邮递员的好基友利腾桑遇到麻烦了:全岛有一些镇子通过水路和旱路相连,走水路必须要用船,在X处下船了船就停在X处。而且岛上只有一条船,下次想走水路还是得回到X处才行;两个镇子之间可能有两条以上的水路或旱路;邮递员必须按照清单上的镇子顺序送快递(镇子可能重复,并且对于重复的镇子不允许一次性处理,比如ABCB的话B一定要按顺序走两次才行)。

测试数据有多组:

N M

x1 y1 t1 sl1

x2 y2 t2 sl2

xM yM tM slM

R

z1 z2zR

N (2 ≤ N ≤ 200) 是镇子的数量,M (1 ≤ M ≤ 10000) 是旱路和水路合计的数量。从第2行到第M + 1行是路径的描述,路径连接xi yi两地,路径花费 ti (1 ≤ ti ≤ 1000)时间,sli 为L时表示是旱路,S时表示是水路。可能有两条及以上路径连接两个镇子,并且路径都是双向的。

M + 2行的R是利腾需要去的镇子的数量,M + 3是利腾需要去的镇子的编号。

初始状态利腾和船都在第一个镇子,且肯定有方法达到需要去的镇子。

测试数据为0 0的时候表示终止。

思路:

先用Floyd预处理出单独走水路s或陆路l的两两之间的最短路。

d[i][j]表示到序列第i点时船停在j,已经去了第i个镇子后,船停在第j个镇子里的状态下的最短路。

状态转移:人从a到b,船从c到d,若船动加上l[a,c]+s[c,d]+l[d,b],若船不动则只要加上l[a][b]。

然后ijk三重循环更新dp,其中递推公式思路:

在推导ik的时候,定义一个中间状态j表示先从i-1走旱路到j,然后从j走水路去k,最后从k走旱路去i,于是就把船扔在了k。

如果j==k的时候就不需要绕圈子了。

#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; int s[210][210];//水路
int l[210][210];//陆路
int d[1010][210];//dp
int b[1010];//目标路线 const int INF = 0x3f3f3f3f; void Floyd(int n)
{
for (int k = 1; k <= n; ++k)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
s[i][j] = min(s[i][j], s[i][k] + s[k][j]);
l[i][j] = min(l[i][j], l[i][k] + l[k][j]);
}
}
}
} int main()
{
int n, m, r;
int u, v, c;
char tp[2]; while (scanf("%d%d", &n, &m) != EOF && n)
{
memset(s, INF, sizeof(s));
memset(l, INF, sizeof(l));
memset(d, INF, sizeof(d)); while (m--)
{
scanf("%d%d%d%s", &u, &v, &c, tp);
if (tp[0] == 'L')
{
l[u][v] = min(l[u][v], c);
l[v][u] = min(l[v][u], c);
}
else
{
s[u][v] = min(s[u][v], c);
s[v][u] = min(s[v][u], c);
}
} for (int i = 1; i <= n; ++i)
{
l[i][i] = 0;
s[i][i] = 0;
} scanf("%d", &r); for (int i = 1; i <= r; ++i)
{
scanf("%d", &b[i]);
} Floyd(n); for (int i = 1; i <= n; ++i)
{
d[1][i] = min(d[1][i], s[b[1]][i] + l[i][b[1]]);
} for (int i = 1; i <= r; ++i)
{
for (int j = 1; j <= n; ++j)
{
//if (l[j][b[i]] >= INF) continue; //剪枝
for (int k = 1; k <= n; ++k)
{
//if (d[i - 1][k] >= INF) continue; //剪枝
if (j == k)
{
if (l[b[i - 1]][b[i]] < INF)
{
d[i][j] = min(d[i][j], d[i - 1][k] + l[b[i - 1]][b[i]]);
}
}
else
{
//三个INF相加可能上溢
if (l[b[i - 1]][k] < INF && s[k][j] < INF && l[j][b[i]] < INF)
{
d[i][j] = min(d[i][j], d[i - 1][k] + l[b[i - 1]][k] + s[k][j] + l[j][b[i]]);
}
}
}
}
} int ans = INF;
for (int j = 1; j <= n; ++j)
{
ans = min(ans, d[r][j]);
}
printf("%d\n", ans);
}
return 0;
}

AOJ 2200 Mr. Rito Post Office (floyd+DP)的更多相关文章

  1. AOJ 2200 Mr. Rito Post Office(Floyd+单调DP)

    [题目链接] http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2200 [题目大意] 一张图中有陆路和水路,水路必须要有船才能走,当船 ...

  2. AOJ 2200 Mr. Rito Post Office

    Mr. Rito Post Office Time Limit : 8 sec, Memory Limit : 65536 KB Problem D: Mr. Rito Post Office あなた ...

  3. Aizu - 2200 Mr. Rito Post Office

    题意:/*你是某个岛国(ACM-ICPC Japan)上的一个苦逼程序员,你有一个当邮递员的好基友利腾桑遇到麻烦了:全岛有一些镇子通过水路和旱路相连,走水路必须要用船,在X处下船了船就停在X处.而且岛 ...

  4. Mr. Rito Post Office [Aizu-2200] [图论] [DP]

    题意:你是某个岛国(ACM-ICPC Japan )上的一个苦逼程序员,你有一个当邮递员的好基友利腾桑遇到麻烦了:全岛有一些镇子通过水路和旱路相连,走水路必须要用船,在X处下船了船就停在X处.而且岛上 ...

  5. ACdreamOJ 1154 Lowbit Sum (数字dp)

    ACdreamOJ 1154 Lowbit Sum (数位dp) ACM 题目地址:pid=1154" target="_blank" style="color ...

  6. poj2342 Anniversary party (树形dp)

    poj2342 Anniversary party (树形dp) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9128   ...

  7. 「SDOI2016」储能表(数位dp)

    「SDOI2016」储能表(数位dp) 神仙数位 \(dp\) 系列 可能我做题做得少 \(QAQ\) \(f[i][0/1][0/1][0/1]\) 表示第 \(i\) 位 \(n\) 是否到达上界 ...

  8. 【HDU1693】Eat the Trees(插头dp)

    [HDU1693]Eat the Trees(插头dp) 题面 HDU Vjudge 大概就是网格图上有些点不能走,现在要找到若干条不相交的哈密顿回路使得所有格子都恰好被走过一遍. 题解 这题的弱化版 ...

  9. 【BZOJ1814】Ural 1519 Formula 1 (插头dp)

    [BZOJ1814]Ural 1519 Formula 1 (插头dp) 题面 BZOJ Vjudge 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...

随机推荐

  1. 从池子里的beta看秋香, 个性迥异

    从池子里的beta看秋香, 个性迥异 前文里那十只个股为例, 统计了它们的beta值. 回顾如下: Num name code Beta 0 深圳燃气 601139 0.710 公用事业 1 分众传媒 ...

  2. readline.c

    一.第一版 #include <unistd.h> #include <errno.h> ssize_t readline(int fd, void *vptr, size_t ...

  3. luogu P1053 篝火晚会

    传送门 首先如果题目的目标状态不是一个环就不合法 然后先把这个环搞出来,然后每个位置上的数对这个数对应的位置连边,可以发现有若干个环,而只要对这些环执行操作就好了,答案上界显然是\(n\).然后,如果 ...

  4. Ubuntu16.04安装搜狗拼音输入法(中文输入法)

    虽然网上有很多教程,但是我觉得我的很适合那些真正的小白... 1.下载文件 由于我要给多台电脑安装搜狗输入法,所以用的是文件夹安装,不是命令行安装. 打开官网http://pinyin.sogou.c ...

  5. 第18月第19天 masonry等分 uilabel sizetofit

    1.masonry等分 mas_distributeViewsAlongAxis MASAxisTypeHorizontal 2.uilabel sizetofit +(CGSize)labSizeW ...

  6. Pyqt5自定义浏览器

    from PyQt5.QtWebChannel import QWebChannel from PyQt5.QtWebEngineWidgets import QWebEngineView from ...

  7. mysql 查询优化 ~explain解读之extra解读

    一 explain 常用状态 1 using filesort 常见于order by 字段 无法走索引造成,文件排序.需要注意优化,复杂条件可以选择建立联合索引进行优化2 using join bu ...

  8. CentOS中安装Nginx

    一.背景 最近在写一些自己的项目,用到了nginx,所以自己动手来在Centos7上安装nginx,以下是安装步骤. 二.基本概念以及应用场景 1.什么是nginx Nginx是一款使用C语言开发的高 ...

  9. Django开发笔记五

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.页面继承 定义base.html: <!DOC ...

  10. WinEdt 和 Sumatra 双向关联设置

    (1)配置PDF Viewer,在菜单栏选Options -> Execution Modes ->PDF Viewer ->点击右侧的"Browse"按钮,在弹 ...