//给一个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. 深度学习方法(五):卷积神经网络CNN经典模型整理Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术感兴趣的同学加入. 关于卷积神经网络CNN,网络和文献中 ...

  2. 给定一列数字将其平移n位

    原题的意思是给定一个指定长度的数组,然后接受一个数字m,将原数组前m位移动到最后,且顺序不变. 看到这个题,想到的第一个方法就是在用一个数组来储存改变后的数字,代码如下 int func(){ int ...

  3. 何時需要重启 OFBiz

    你在做如下更改時需要重新启動OFBiz服務器: - Java文件(記得要重新編譯) - 配置/.properties文件 - entitymodel或entitygroup XML定義文件 - 服務或 ...

  4. 182. Duplicate Emails

    Write a SQL query to find all duplicate emails in a table named Person. +----+---------+ | Id | Emai ...

  5. AC日记——[SCOI2009]游戏 bzoj 1025

    [SCOI2009]游戏 思路: 和为n的几个数最小公倍数有多少种. dp即可: 代码: #include <bits/stdc++.h> using namespace std; #de ...

  6. CentOS7配置redis主从复制

    规划 ip port role 192.168.1.31 6379 master 192.168.1.32 6379 slave 192.168.1.33 6379 slave 0.关闭防火墙 sys ...

  7. Mongodb 3.4 Replication

    官方文档:https://docs.mongodb.com/manual/replication/ 关于ReplSet的文档 https://docs.mongodb.com/manual/refer ...

  8. python抓取网页图片的小案例

    1.分析 ,要抓取的页面的信息以及对应的源码信息 blog.sina.com.cn/s/blog 93dc666c0101b1bj.html 2.代码模块: 导入正则表达的模块 导入url相关的模块 ...

  9. 【tomcat】获取访问者真实IP

    1.直接访问tomcat的情况 通过下面这段代码可以获取: String ip = request.getHeader("x-forwarded-for"); if(ip == n ...

  10. python搜索引擎(转)

    用python如何实现一个站内搜索引擎? 先想想搜索引擎的工作流程: 1.网页搜集.用深度或者广度优先的方法搜索某个网站,保存下所有的网页,对于网页的维护采用定期搜集和增量搜集的方式. 2.建立索引库 ...