POJ 3592 Instantaneous Transference

题目链接

题意:一个图。能往右和下走,然后有*能够传送到一个位置。'#'不能走。走过一个点能够获得该点上面的数字值,问最大能获得多少

思路:因为有环先强连通缩点。然后问题转化为dag,直接dp就可以

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std; const int N = 1605;
const int d[2][2] = {0, 1, 1, 0}; int t, n, m, val[N];
char str[45][45];
vector<int> g[N], scc[N];
stack<int> S; int pre[N], dfn[N], dfs_clock, sccno[N], sccn, scc_val[N]; void dfs_scc(int u) {
pre[u] = dfn[u] = ++dfs_clock;
S.push(u);
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
if (!pre[v]) {
dfs_scc(v);
dfn[u] = min(dfn[u], dfn[v]);
} else if (!sccno[v]) dfn[u] = min(dfn[u], pre[v]);
}
if (dfn[u] == pre[u]) {
sccn++;
int sum = 0;
while (1) {
int x = S.top(); S.pop();
sum += val[x];
sccno[x] = sccn;
if (u == x) break;
}
scc_val[sccn] = sum;
}
} void find_scc() {
dfs_clock = sccn = 0;
memset(pre, 0, sizeof(pre));
memset(sccno, 0, sizeof(sccno));
for (int i = 0; i < n * m; i++)
if (!pre[i]) dfs_scc(i);
} int dp[N]; int dfs(int u) {
if (dp[u] != -1) return dp[u];
dp[u] = 0;
for (int i = 0; i < scc[u].size(); i++) {
int v = scc[u][i];
dp[u] = max(dp[u], dfs(v));
}
dp[u] += scc_val[u];
return dp[u];
} int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
for (int i = 0; i < n * m; i++) g[i].clear();
for (int i = 0; i < n; i++)
scanf("%s", str[i]);
memset(val, 0, sizeof(val));
int a, b;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (str[i][j] == '#') continue;
if (str[i][j] >= '0' && str[i][j] <= '9') val[i * m + j] = str[i][j] - '0';
if (str[i][j] == '*') {
scanf("%d%d", &a, &b);
g[i * m + j].push_back(a * m + b);
}
for (int k = 0; k < 2; k++) {
int x = i + d[k][0];
int y = j + d[k][1];
if (x < 0 || x >= n || y < 0 || y >= m || str[x][y] == '#') continue;
g[i * m + j].push_back(x * m + y);
}
}
}
find_scc();
for (int i = 1; i <= sccn; i++) scc[i].clear();
for (int u = 0; u < n * m; u++) {
for (int j = 0; j < g[u].size(); j++) {
int v = g[u][j];
if (sccno[u] == sccno[v]) continue;
scc[sccno[u]].push_back(sccno[v]);
}
}
memset(dp, -1, sizeof(dp));
printf("%d\n", dfs(sccno[0]));
}
return 0;
}

POJ 3592 Instantaneous Transference(强连通+DP)的更多相关文章

  1. poj 3592 Instantaneous Transference 【SCC +缩点 + SPFA】

    Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6204   Accep ...

  2. POJ 3592 Instantaneous Transference(强联通分量 Tarjan)

    http://poj.org/problem?id=3592 题意 :给你一个n*m的矩阵,每个位置上都有一个字符,如果是数字代表这个地方有该数量的金矿,如果是*代表这个地方有传送带并且没有金矿,可以 ...

  3. poj 3592 Instantaneous Transference

    http://poj.org/problem?id=3592 #include <cstdio> #include <cstring> #include <algorit ...

  4. poj 3592 Instantaneous Transference 缩点+最长路

    题目链接 给一个n*m的图, 从0, 0这个点开始走,只能向右和向下. 图中有的格子有值, 求能获得的最大值. 其中有些格子可以传送到另外的格子, 有些格子不可以走. 将图中的每一个格子都看成一个点, ...

  5. Instantaneous Transference(强连通分量及其缩点)

    http://poj.org/problem?id=3592 题意:给出一个n*m的矩阵,左上角代表起始点,每个格子都有一定价值的金矿,其中‘#’代表岩石不可达,‘*’代表时空门可以到达指定格子,求出 ...

  6. POJ3592 Instantaneous Transference 强连通+最长路

    题目链接: id=3592">poj3592 题意: 给出一幅n X m的二维地图,每一个格子可能是矿区,障碍,或者传送点 用不同的字符表示: 有一辆矿车从地图的左上角(0,0)出发, ...

  7. 【POJ 3071】 Football(DP)

    [POJ 3071] Football(DP) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4350   Accepted ...

  8. poj 3311(状态压缩DP)

    poj  3311(状态压缩DP) 题意:一个人送披萨从原点出发,每次不超过10个地方,每个地方可以重复走,给出这些地方之间的时间,求送完披萨回到原点的最小时间. 解析:类似TSP问题,但是每个点可以 ...

  9. poj 1185(状态压缩DP)

    poj  1185(状态压缩DP) 题意:在一个N*M的矩阵中,‘H'表示不能放大炮,’P'表示可以放大炮,大炮能攻击到沿横向左右各两格,沿纵向上下各两格,现在要放尽可能多的大炮使得,大炮之间不能相互 ...

随机推荐

  1. 通过DNS通道传输的交互式PowerShell脚本

    摘自:http://www.freebuf.com/sectool/90616.html 欢迎来到一周PowerShell脚本的第五天,今天我们将讨论使用ICMP和DNS的交互式PowerShell脚 ...

  2. Gojs学习史(一):基本定义

    1. gojs定义 初始化时,先简化gojs本身的方法: var Go = go.GraphObject.make; //简化方法 1.1 画布定义 在声明了Go方法之后,接下来就是定义画布: myD ...

  3. Codeforces 667C Reberland Linguistics 记忆化搜索

    链接 Codeforces 667C Reberland Linguistics 题意 给你一个字符串,除去前5个字符串后,使剩下的串有长度为2或3的词根组成,相邻的词根不能重复.找到所有的词根 思路 ...

  4. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  5. PostgreSQL Replication之第五章 设置同步复制(2)

    5.2 理解实际影响和性能 在本章中,我们已经讨论了实际影响以及性能影响.但是,有什么好的理论性的例子吗?让我们做一个简单的基准测试,看看复制是怎么做的.我们做这样的测试来为您显示各种耐久性的级别不只 ...

  6. python制造模块

    制造模块: 方法一: 1.mkdir /xxcd /xx 2.文件包含: 模块名.py setup.py setup.py内容如下:#!/usr/bin/env pythonfrom distutil ...

  7. 4、Go for循环

    package main import "fmt" func main(){ //for 循环是go语言唯一的循环结构,分为三种类型 //第一种 类似while i:=1 for ...

  8. Linux Shell脚本编程-函数

    函数介绍  定义:把一段独立功能的的代码当做一个整体,并为之一个名字,命名的代码段,此即为函数:  功能:函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程.  注意: ...

  9. mpstat---用于多CPU环境下,显示各个可用CPU的状态

    mpstat命令指令主要用于多CPU环境下,它显示各个可用CPU的状态系你想.这些信息存放在/proc/stat文件中.在多CPUs系统里,其不但能查看所有CPU的平均状况信息,而且能够查看特定CPU ...

  10. caioj 1106 树形动态规划(TreeDP)1:加分二叉树

    解这道题的前提是非常熟悉中序遍历的方式 我就是因为不熟悉而没有做出来 中序遍历是5 7 1 2 10的话,如果1是根节点 那么5 7 1就是1的左子树,2, 10就是右子树 这就有点中链式dp的味道了 ...