题目链接

给一个n*m的图, 从0, 0这个点开始走,只能向右和向下。 图中有的格子有值, 求能获得的最大值。 其中有些格子可以传送到另外的格子, 有些格子不可以走。

将图中的每一个格子都看成一个点, 然后对它右边和下边的点连边, 如果是'#’就continue,  如果可以传送, 那么就对传送到的那个点连边, 同时也要向右边和下边连边, 因为可以选择不传送。 然后缩点求最长路就可以。

一个数组没有初始化RE了好多发.....

 #include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, a, n) for(int i = a; i<n; i++)
#define ull unsigned long long
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {, }, {, }, {, -}, {, } };
const int maxn = ;
const int maxE = 1e5+;
int num, val[maxn], n, m, low[maxn], dfn[maxn], s[maxn], instack[maxn], st[maxn], top, cnt, cnum;
int sumval[maxn], head2[maxE], head[maxE], dis[maxn];
char g[][];
struct node
{
int to, nextt;
}e[maxE], e2[maxE];
int dfs(int u) {
if(~dis[u])
return dis[u];
int ans = sumval[u], ret = ;
for(int i = head2[u]; ~i; i = e2[i].nextt) {
int v = e2[i].to;
ret = max(ret, dfs(v));
}
return dis[u] = ret+ans;
}
void add2(int u, int v) {
e2[num].to = v;
e2[num].nextt = head2[u];
head2[u] = num++;
}
void rebuild() {
num = ;
for(int i = ; i<n*m; i++) {
int u = s[i];
for(int j = head[i]; ~j; j = e[j].nextt) {
int v = e[j].to;
if(s[v] == u)
continue;
add2(u, s[v]);
}
}
}
void tarjan(int u) {
instack[u] = ;
st[top++] = u;
dfn[u] = low[u] = ++cnt;
for(int i = head[u]; ~i; i = e[i].nextt) {
int v = e[i].to;
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[v], low[u]);
} else if(instack[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u]) {
++cnum;
int x;
do {
x = st[--top];
instack[x] = ;
s[x] = cnum;
sumval[cnum] += val[x];
} while( x!=u );
}
}
int judge(int x, int y) {
if(x>=&&x<n&&y>=&&y<m&&g[x][y]!='#')
return ;
return ;
}
void add(int u, int v) {
e[num].to = v;
e[num].nextt = head[u];
head[u] = num++;
}
void build()
{
scanf("%d%d", &n, &m);
for(int i = ; i<n; i++)
scanf("%s", g[i]);
int x, y;
for(int i = ; i<n; i++) {
for(int j = ; j<m; j++) {
if(g[i][j] == '#')
continue;
if(g[i][j] == '*') {
scanf("%d%d", &x, &y);
add(i*m+j, x*m+y);
}
if(g[i][j]!='*')
val[i*m+j] = g[i][j]-'';
for(int k = ; k<; k++) {
int tmpx = i+dir[k][];
int tmpy = j+dir[k][];
if(judge(tmpx, tmpy))
add(i*m+j, tmpx*m+tmpy);
}
}
}
}
void init() {
num = top = cnum = cnt = ;
mem(dfn);
mem(sumval);
mem1(head);
mem1(head2);
mem1(dis);
mem(instack);
mem(low);
mem(val);
mem(s);
}
int main()
{
int t, ans;
cin>>t;
while(t--) {
init();
build(); //建图
tarjan(); //缩点
rebuild(); //对缩点后的图建图
ans = dfs(s[]); //记忆化搜索求最长路
cout<<ans<<endl;
}
return ;
}

poj 3592 Instantaneous Transference 缩点+最长路的更多相关文章

  1. POJ 3592 Instantaneous Transference(强连通+DP)

    POJ 3592 Instantaneous Transference 题目链接 题意:一个图.能往右和下走,然后有*能够传送到一个位置.'#'不能走.走过一个点能够获得该点上面的数字值,问最大能获得 ...

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

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

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

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

  4. poj 3592 Instantaneous Transference

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

  5. bzoj1179 [Apio2009]Atm——缩环最长路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1179 tarjan 缩环,然后求到有酒吧的点的最长路即可: 但一开始想缩环后用拓扑序求答案, ...

  6. ZOJ 3795:Grouping(缩点+最长路)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5303 题意:有n个人m条边,每条边有一个u,v,代表u的年龄大于等于v,现在要 ...

  7. POJ 1949 Chores(DAG上的最长路 , DP)

    题意: 给定n项任务, 每项任务的完成用时t和完成每项任务前需要的k项任务, 求把所有任务完成的最短时间,有当前时间多项任务都可完成, 那么可以同时进行. 分析: 这题关键就是每项任务都会有先决条件, ...

  8. POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;&amp; SPFA求最长路 &amp;&amp; 经典】

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

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

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

随机推荐

  1. Quartz 2D 概述

    Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境.我们可以使用Quartz 2D API来实现许多功能,如基本路径的绘制.透明度.描影.绘制阴影.透明层.颜色管理.反锯齿 ...

  2. My SQL和LINQ 实现ROW_NUMBER() OVER以及Fatal error encountered during command execution

    Oracle 和SQL server都有ROW_NUMBER() OVER这个功能函数,主要用于分组排序,而MySQL 却没有 SELECT * FROM (SELECT ROW_NUMBER() O ...

  3. 【转】java jawin api 中文 invoke方法

    org.jawin Class FuncPtr java.lang.Object org.jawin.FuncPtr ----------------------------------------- ...

  4. 学习dijk最短路径中

    #include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #i ...

  5. C语言统计运行时间

    clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t. 在MSDN中,查得对clock函数定义如下: clock_t clock(void) ;   简单而言,就是该程序从启动 ...

  6. 《javascript dom编程艺术》笔记(一)——优雅降级、向后兼容、多个函数绑定onload函数

    刚刚开始自学前端,如果不对请指正:欢迎各位技术大牛指点. 开始学习<javascript dom编程艺术>,整理一下学习到的知识.今天刚刚看到第六章,记下get到的几个知识点. 优雅降级 ...

  7. c/c++实现混合编程

    在开发中大家经常会使用到c与c++混合编程,这样能够更好的实现功能模块.刚学习了一下c和c++的混合编程,参考了网上的相关知识,在这里留下要点,方便以后进行查阅. 1.extern关键字 extern ...

  8. 收藏的技术文章链接(ubuntu,python,android等)

    我的收藏 他山之石,可以攻玉 转载请注明出处:https://ahangchen.gitbooks.io/windy-afternoon/content/ 开发过程中收藏在Chrome书签栏里的技术文 ...

  9. linux搭建php

    http://www.cnblogs.com/wubaiqing/archive/2011/11/08/2241195.html 四,启动php-fpm & Nginx /usr/local/ ...

  10. Navicat for mysql 导出sql文件 导入sql文件

    运行速度快 不受大小限制 安全高效