poj3592 Instantaneous Transference tarjan缩点+建图
//给一个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缩点+建图的更多相关文章
- poj2186Popular Cows+tarjan缩点+建图
传送门: 题意: 给出m条关系,表示n个牛中的崇拜关系,这些关系满足传递性.问被所有牛崇拜的牛有几头: 思路: 先利用tarjan缩点,同一个点中的牛肯定就是等价的了,建立新的图,找出其中出度为0的点 ...
- POJ3592 Instantaneous Transference tarjan +spfa
链接:http://poj.org/problem?id=3592 题意:题目大意:给定一个矩阵,西南角为出发点,每个单位都有一订价值的金矿(#默示岩石,不成达,*默示时佛门,可以达到指定单位),队# ...
- 炸弹:线段树优化建边+tarjan缩点+建反边+跑拓扑
这道题我做了有半个月了...终于A了... 有图为证 一句话题解:二分LR线段树优化建边+tarjan缩点+建反边+跑拓扑统计答案 首先我们根据题意,判断出来要炸弹可以连着炸,就是这个炸弹能炸到的可以 ...
- HDU 1045 Fire Net(行列匹配变形+缩点建图)
题意:n*n的棋盘上放置房子.同一方同一列不能有两个,除非他们之间被墙隔开,这种话. 把原始图分别按行和列缩点 建图:横竖分区.先看每一列.同一列相连的空地同一时候看成一个点,显然这种区域不可以同一时 ...
- POJ3592 Instantaneous Transference 强连通+最长路
题目链接: id=3592">poj3592 题意: 给出一幅n X m的二维地图,每一个格子可能是矿区,障碍,或者传送点 用不同的字符表示: 有一辆矿车从地图的左上角(0,0)出发, ...
- hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
The King’s Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- POJ3592 Instantaneous Transference题解
题意: 给一个矩形,矩形中某些点有一定数量的矿石,有些点为传送点,有些点为障碍.你驾驶采矿车(ore-miner truck,我也不知道是什么),从左上角出发,采尽量多的矿石,矿石不可再生.不能往左边 ...
- Tarjan缩点+DAG图dp
题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...
- We Need More Bosses CodeForces - 1000E(缩点 建图 求桥 求直径)
题意: 就是求桥最多的一条路 解析: 先求连通分量的个数 然后缩点建图 求直径即可 #include <bits/stdc++.h> #define mem(a, b) memset(a ...
随机推荐
- Maximum Gap——桶排序
Given an unsorted array, find the maximum difference between the successive elements in its sorted f ...
- 理解JWT(Json Web Token)
这篇文章写得不错: 理解JWT(JSON Web Token)认证及python实践,这里不做转载,仅摘要如下,有删改,仅做个人学习,感谢原作者. 常用认证机制: 1)HTTP basic Auth: ...
- AC日记——明明的烦恼 bzoj 1005
1005 思路: prufer编码+组合数: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 #de ...
- 三十八 ThreadLocal
在多线程环境下,每个线程都有自己的数据.一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁. 但是局部变量也有问题,就是在函数调用的 ...
- 数据库的主从复制常用Xshell命令
mysql配置 1.设置数据库用户名和密码 mysqladmin -u root password "root" 2.打开3306端口号 iptables -I INPUT -p ...
- HDU 6467.简单数学题-数学题 (“字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛)
简单数学题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- 【转载】万能adapter
adapter总是自己写,其实使用现成的框架会节省不少代码 原文地址:https://github.com/hongyangAndroid/baseAdapter base-adapter Andro ...
- CF1025C Plasticine zebra【环状字符串/思维】
给你一个长度为 \(\left|s\right|\) 的01串 \(s\) ,每次操作你可以任选一个 \(k\) ,使01串的 \([1,k]\) 和 \((k,\left|s\right|]\) 分 ...
- 线性基【CF845G】Shortest Path Problem?
Description 给定一张 \(n\) 个点 \(m\) 条边的无向图,一开始你在点 \(1\),且价值为 \(0\) 每次你可以选择一个相邻的点,然后走过去,并将价值异或上该边权 如果在点 \ ...
- [USACO 2016 Dec Gold] Tutorial
Link: 传送门 A: 贪心从小到大插入,用并查集维护连通性 #include <bits/stdc++.h> using namespace std; #define X first ...