题目链接

给一个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. Datatable根据多行排序

    DataTable dt = new DataTable(); dt.Columns.Add("ID", typeof(int)); dt.Columns.Add("Na ...

  2. C#之多线程编程

    一.进程与线程 进程(Process)是对一段静态指令序列(程序)的动态执行过程,是系统进行资源分配和调度的一个基本单位.与进程相关的信息包括进程的用户标识,正在执行的已经编译好的程序,进程程序和数据 ...

  3. 浅谈C中的指针和数组(六)

    数组和指针,原本不想在写了,觉得这部分差不多了,但是自己在写程序的时候还是发现了一个错误.首先说一下我的要求: 给一个函数传递一个二维数组,然后我想在这个函数里面计算这个数组的行数. 写个类似的错误D ...

  4. HTML5 canvas入门

    HTML5 Canvas入门 <canvas> 标签定义图形,比如图表和其他图像,您必须使用脚本来绘制图形.在画布上(Canvas)画一个红色矩形,渐变矩形,彩色矩形,和一些彩色的文字. ...

  5. FAQ:Python环境变量配置

    Python安装安装成,需要配置环境变量: 默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1. 首先需要在系统中注册 ...

  6. C++ 下 typeof 的实现

    现在我们有这样一坨代码: std::vector<int> arr; // ... for(std::vector<int>::iterator iter = arr.begi ...

  7. java 集合类说明与区别

    集合类说明及区别Collection├List│├LinkedList│├ArrayList│└Vector│ └Stack└SetMap├Hashtable├HashMap└WeakHashMap ...

  8. keep健身计划

    下一个月计划 1keep二周计划 2百度第一期学完 3百度前端技术学院提升

  9. Qt程序设计——txt文本中获取字符串的问题

    QT对txt文本进行读写一般是采用QFile和QTextStream结合使用,在此不细说,主要说一下读取txt文本的注意事项.因为txt文本中有中文也有英文还有数字,要准确获得需要的字串可就要多一个心 ...

  10. Unity3D游戏开发从零单排(五) - 导入CS模型到Unity3D

    游戏动画基础 Animation组件 Animation组件是对于老的动画系统来说的. 老的动画形同相应的动画就是clip,每一个运动都是一段单独的动画,使用Play()或CrossFade(),直接 ...