//给一个n*m的地图。坦克从(0 , 0)開始走
//#表示墙不能走,*表示传送门能够传送到指定地方,能够选择也能够选择不传送
//数字表示该格的矿石数,
//坦克从(0,0)開始走。仅仅能往右和往下走。
//问最多能得到多少矿石
//直接建图,但因为有传送门。须要缩点
//然后用dfs直接搜一条权值最大的路
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<queue>
using namespace std ;
const int maxn = 2010 ;
int dfn[maxn] , low[maxn] , vis[maxn] , stack[maxn] ;int ans ;
int head[maxn*maxn] , belong[maxn] ,isstack[maxn] ;
int num , top , nedge , step ;int X[maxn] , Y[maxn] ; int n, m ;
int w[maxn];int a[maxn];int len;int visit[50][50];
int map[maxn][maxn] ;int pos ;
char str[maxn][maxn] ;
int dx[2] = {0,1} ;
int dy[2] = {1,0} ;
vector<int>vec[maxn] ;
struct Edge
{
int v ;
int next ;
}edge[maxn*maxn] ;
void addedge(int u , int v)
{
edge[nedge].v = v ;
edge[nedge].next = head[u] ;
head[u] = nedge++ ;
}
void init()
{
for(int i = 0;i <= n*m;i++)
vec[i].clear() ;
memset(head , -1 , sizeof(head)) ;
memset(w ,0 , sizeof(w)) ;
memset(dfn , 0 , sizeof(dfn)) ;
memset(isstack ,0 , sizeof(isstack)) ;
memset(map , 0 , sizeof(map)) ;
memset(vis ,0 , sizeof(vis)) ;
memset(a ,0 , sizeof(a)) ;
num = top = nedge = step = len = 0 ;
}
void tarjan(int u)
{
stack[++top] = u ;
isstack[u] = 1 ;
low[u] = dfn[u] = ++step ;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v ;
if(!dfn[v])
{
tarjan(v) ;
low[u] = min(low[u] , low[v]) ;
}
else if(isstack[v])
low[u] = min(low[u] , dfn[v]) ;
}
if(low[u] == dfn[u])
{
num++ ;
int v = -1 ;
while(u != v)
{
v = stack[top--] ;
isstack[v] = 0 ;
belong[v] = num ;
w[num] += a[v];
if(v==0)pos = num ;
}
}
}
void build_tree()
{
for(int i = 0;i <= n*m;i++)
for(int j = head[i] ; j != -1 ; j =edge[j].next)
{
int u = belong[i] ;
int v = belong[edge[j].v] ;
if(u == v)continue ;
vec[u].push_back(v) ;
vis[v] = 1 ;
}
}
int dfs(int u)
{
int ma = 0 ;
for(int i = 0;i < vec[u].size() ;i++)
{
int v = vec[u][i] ;
ma = max(ma , dfs(v)) ;
}
ans = max(ans , ma+w[u]) ;
return ma + w[u] ;
}
int main()
{
//freopen("in.txt" , "r" , stdin) ;
int t ;
scanf("%d" , &t) ;
while(t--)
{
scanf("%d%d" , &n , &m) ;
init() ;
ans = 0 ;
for(int i = 0;i < n;i++)
scanf("%s" ,str[i]) ;
for(int i = 0;i < n;i++)
{
for(int j = 0;j < m;j++)
if(str[i][j] != '#')
{
if(str[i][j] == '*')
{
X[++len] = i ;
Y[len] = j ;
a[i*m+j] = 0 ;
}
else
{
a[i*m + j] = str[i][j] - '0' ;
ans = max(ans , a[i*m+j]) ;
}
for(int k = 0 ;k < 2;k++)
{
int nx = i + dx[k] ;
int ny = j + dy[k] ;
if((nx >= n || ny >= m))
addedge(i*m + j , n*m) ;
else if(str[nx][ny] != '#')
addedge(i*m + j , nx*m + ny) ;
}
}
}
for(int i = 1;i <= len ;i++)
{
int u , v ;
scanf("%d%d" , &u , &v) ;
addedge(X[i]*m+ Y[i] , u*m+v) ;
}
pos = 0 ;
for(int i = 0;i <= n*m;i++)
if(head[i] != -1 && !dfn[i])
tarjan(i) ;
if(!pos)
{
cout<<ans<<endl;
continue ;
}
build_tree() ;
dfs(pos) ;
printf("%d\n" ,ans) ;
}
}

poj3592 Instantaneous Transference tarjan缩点+建图的更多相关文章

  1. poj2186Popular Cows+tarjan缩点+建图

    传送门: 题意: 给出m条关系,表示n个牛中的崇拜关系,这些关系满足传递性.问被所有牛崇拜的牛有几头: 思路: 先利用tarjan缩点,同一个点中的牛肯定就是等价的了,建立新的图,找出其中出度为0的点 ...

  2. POJ3592 Instantaneous Transference tarjan +spfa

    链接:http://poj.org/problem?id=3592 题意:题目大意:给定一个矩阵,西南角为出发点,每个单位都有一订价值的金矿(#默示岩石,不成达,*默示时佛门,可以达到指定单位),队# ...

  3. 炸弹:线段树优化建边+tarjan缩点+建反边+跑拓扑

    这道题我做了有半个月了...终于A了... 有图为证 一句话题解:二分LR线段树优化建边+tarjan缩点+建反边+跑拓扑统计答案 首先我们根据题意,判断出来要炸弹可以连着炸,就是这个炸弹能炸到的可以 ...

  4. HDU 1045 Fire Net(行列匹配变形+缩点建图)

    题意:n*n的棋盘上放置房子.同一方同一列不能有两个,除非他们之间被墙隔开,这种话. 把原始图分别按行和列缩点 建图:横竖分区.先看每一列.同一列相连的空地同一时候看成一个点,显然这种区域不可以同一时 ...

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

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

  6. hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  7. POJ3592 Instantaneous Transference题解

    题意: 给一个矩形,矩形中某些点有一定数量的矿石,有些点为传送点,有些点为障碍.你驾驶采矿车(ore-miner truck,我也不知道是什么),从左上角出发,采尽量多的矿石,矿石不可再生.不能往左边 ...

  8. Tarjan缩点+DAG图dp

    题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...

  9. We Need More Bosses CodeForces - 1000E(缩点 建图 求桥 求直径)

    题意: 就是求桥最多的一条路 解析: 先求连通分量的个数 然后缩点建图  求直径即可 #include <bits/stdc++.h> #define mem(a, b) memset(a ...

随机推荐

  1. AC日记——「SCOI2015」国旗计划 LiBreOJ 2007

    #2007. 「SCOI2015」国旗计划 思路: 跪烂Claris 代码: #include <cstdio> #include <algorithm> #define ma ...

  2. AC日记——自然数和分解 codevs 2549

    自然数和分解 思路: 水题: 代码: #include <bits/stdc++.h> using namespace std; ][]; int main() { cin>> ...

  3. 基于 Docker 的 DevOps 搭建

    一直对 DevOps 感兴趣,最近心血来潮,搭乘 Docker 搞一搞,Let‘s Go !!! 1.拉取 GitLab  docker pull gitlab/gitlab-ce 2.Run Git ...

  4. Java 中List 集合索引遍历与迭代器遍历

    package yzhou.iterator; import java.util.ArrayList; import java.util.HashSet; import java.util.Itera ...

  5. ZSTU OJ 4272 最佳淘汰算法

    线段树. 处理出每个位置下一个位置是哪里.然后搞个线段树找一下最大值就可以了. #include<map> #include<set> #include<ctime> ...

  6. zookeeper,hadoop安装部署其实与防火墙无关

    网上查看了很多人关于hadoop,zookeeper的文章,大多都把关闭防火墙作为首要前提,个人觉得这大可不必. 首先你需要知道你部署的是什么东西,它需要哪些端口即可.把相关端口打开就可以了啊.然后把 ...

  7. 如何使用Web字体?

    如何使用Web字体 嵌入Web字体的关键是@font-face规则,通过它可以指定浏览器下载web字体的地址,以及如何在样式表中引用该字体 @font-face { font-family: Voll ...

  8. Visual Studio警告IDE0006的解决办法

     Visual Studio警告IDE0006的解决办法 Visual Studio警告IDE0006虽然给出明确的操作过程,但是在实施的过程中,还是有很多地方需要注意.下面以官方的信息,介绍一下注意 ...

  9. ARC-100 C - Linear Approximation

    题面在这里! 可以看成点集{a[i]-i}和b之间距离的和,于是找到中位数就可以直接算了2333. #include<bits/stdc++.h> #define ll long long ...

  10. HDU 6035 Colorful Tree(补集思想+树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 单独考虑 ...