POJ 3592 Instantaneous Transference(强联通分量 Tarjan)
http://poj.org/problem?id=3592
题意 :给你一个n*m的矩阵,每个位置上都有一个字符,如果是数字代表这个地方有该数量的金矿,如果是*代表这个地方有传送带并且没有金矿,可以传送到指定的位置,如果是#代表该位置不可走,初始位置在左上角,只能向下或向右走,并且走到传送带的时候可选择是否传送。问当走出去的时候能获得的最大近况数是多少。
思路 :先将二维矩阵转化成一维的点建图,可以向下向右建图,而且传送带也可以建边,缩点之后再建边,最后用spfa求最长路。
#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h> using namespace std; const int maxn = ;
const int INF = - ; int belong[maxn],instack[maxn],dfn[maxn],low[maxn],g[maxn],map[maxn],c[maxn] ;
//belong[i]指的是i点所在的联通分量的编号。instack模拟的是栈,因为每个节点是要入栈的,来判断是否属于同一个分量
//dfn[i]为搜索i结点的次序编号,Low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号。
//g[i]是指将一个矩阵从0到n*m编号之后的,i点所在的那个位置的宝藏数,map[i]记录的是第i个传送带的位置
//c[i]记录的是第i个联通分量中宝藏的总数。
int cntt,cnt,top,bcc_clock,cntb,n,m,num ;
int head1[maxn] ,head[maxn];
char point[][] ;//输入的地图
int dis[maxn],coun[maxn],index ;
bool vis[maxn],flag[maxn] ;
int dire[][] = {{,},{,}} ; struct node
{
int u,v,w,next ;
} p[maxn] ,ch[maxn]; void addedge(int u,int v)
{
p[cnt].u = u ;
p[cnt].v = v ;
p[cnt].next = head[u] ;
head[u] = cnt++ ;
} void addnode(int u,int v,int w)
{
ch[cntt].u = u ;
ch[cntt].v = v ;
ch[cntt].w = w ;
ch[cntt].next = head1[u] ;
head1[u] = cntt++ ;
} void tarjan(int u)
{
vis[u] = true ;
dfn[u] = low[u] = ++bcc_clock ;
instack[++top] = u ;
for(int i = head[u] ; i+ ; i = p[i].next)
{
int v = p[i].v ;
if(!dfn[v])
{
tarjan(v) ;
low[u] = min(low[u],low[v]) ;
}
else if(vis[v])
low[u] = min(low[u],dfn[v]) ;
}
if(dfn[u] == low[u])
{
cntb++ ;
int v ;
do
{
v = instack[top--] ;
vis[v] = false ;
belong[v] = cntb ;
}
while(v != u) ;
}
} void Init()
{
memset(dfn,,sizeof(dfn)) ;
memset(low,,sizeof(low)) ;
memset(belong,,sizeof(belong)) ;
memset(c,,sizeof(c)) ;
memset(vis,,sizeof(vis)) ;
num = ;
memset(head,-,sizeof(head)) ;
memset(head1,-,sizeof(head1)) ;
cnt = ,top = ,cntb = ,bcc_clock = ,cntt = ;
} bool relax(int u,int v,int w)
{
if(dis[v] < dis[u] + w)
{
dis[v] = dis[u] + w ;
return true ;
}
return false ;
} bool spfa(int u)
{
memset(flag,false,sizeof(flag)) ;
memset(coun,,sizeof(coun)) ;
flag[u] = true ;
for(int i = ; i <= cntb ; i++)
dis[i] = INF ;
queue<int >Q ;
Q.push(u) ;
dis[u] = ;
while(!Q.empty ())
{
int st = Q.front() ;
Q.pop() ;
flag[st] = false ;
for(int i = head1[st] ; i+ ; i = ch[i].next)
{
if(relax(st,ch[i].v,ch[i].w) && !flag[ch[i].v])
{
if((++coun[ch[i].v]) > m*n) return false ;
Q.push(ch[i].v) ;
flag[ch[i].v] = true ;
}
}
}
index = ;
for(int i = ; i <= cntb ; i++)
index = max(index,dis[i]) ;
return true ;
}
int main()
{
int T ;
scanf("%d",&T) ;
while(T--)
{
scanf("%d %d",&n,&m) ;
int cnnt = ;//记录传送带的个数
Init() ;
getchar() ;
for(int i = ; i < n ; i++)
scanf("%s",point[i]) ;
for(int i = ; i < n ; i++)
{
for(int j = ; j < m ; j++)
{
int k = i*m+j ;
if(point[i][j] == '#')
{
g[k] = - ;
continue ;
}
else
{
if(point[i][j] == '*')
{
map[cnnt++] = k ;
g[k] = ;
}
else if(point[i][j] >= '' && point[i][j] <= '')
g[k] = point[i][j] - '' ;
for(int ii = ; ii < ; ii++)
{
int xx = i+dire[ii][] ;
int yy = j+dire[ii][] ;
if(xx < n && yy < m)
{
if(point[xx][yy] != '#')
addedge(k,xx*m+yy) ;
}
}
}
}
}
for(int i = ; i < cnnt ; i++)
{
int x,y ;
scanf("%d %d",&x,&y) ;
if(point[x][y] != '#')
addedge(map[i],x*m+y) ;
}
// Init() ;
for(int i = ; i < n*m ; i++)
if(!dfn[i]) tarjan(i) ;
for(int i = ; i < n*m ; i++)
c[belong[i]] += g[i] ;
addnode(,belong[],c[belong[]]);//缩点之后的建边
for(int i = ; i < n*m ; i++)
{
for(int j = head[i] ; j + ; j = p[j].next)
{
int v = p[j].v ;
if(belong[i] != belong[v])
{
addnode(belong[i],belong[v],c[belong[v]]) ;//两个点不属于同一个联通分量
}
}
}
spfa() ;//求最长路
printf("%d\n",index) ;
} return ;
}
POJ 3592 Instantaneous Transference(强联通分量 Tarjan)的更多相关文章
- POJ 3592 Instantaneous Transference(强连通+DP)
POJ 3592 Instantaneous Transference 题目链接 题意:一个图.能往右和下走,然后有*能够传送到一个位置.'#'不能走.走过一个点能够获得该点上面的数字值,问最大能获得 ...
- POJ 2186 Popular Cows(强联通分量)
题目链接:http://poj.org/problem?id=2186 题目大意: 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种 ...
- POJ 2186-Popular Cows (图论-强联通分量Korasaju算法)
题目链接:http://poj.org/problem?id=2186 题目大意:有n头牛和m对关系, 每一对关系有两个数(a, b)代表a牛认为b牛是“受欢迎”的,且这种关系具有传递性, 如果a牛认 ...
- 强联通分量-tarjan算法
定义:在一张有向图中,两个点可以相互到达,则称这两个点强连通:一张有向图上任意两个点可以相互到达,则称这张图为强连通图:非强连通图有极大的强连通子图,成为强联通分量. 如图,{1},{6}分别是一个强 ...
- [vios1023]维多利亚的舞会3<强联通分量tarjan>
题目链接:https://vijos.org/p/1023 最近在练强联通分量,当然学的是tarjan算法 而这一道题虽然打着难度为3,且是tarjan算法的裸题出没在vijos里面 但其实并不是纯粹 ...
- poj 3592 Instantaneous Transference 【SCC +缩点 + SPFA】
Instantaneous Transference Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6204 Accep ...
- POJ 3114 Countries in War(强联通分量+Tarjan)
题目链接 题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0. 思路 :强连通分量缩点之后,求最短路.以前写过,总感觉记忆不深,这次自己敲完再写了一遍. #include ...
- poj 3592 Instantaneous Transference
http://poj.org/problem?id=3592 #include <cstdio> #include <cstring> #include <algorit ...
- poj 3592 Instantaneous Transference 缩点+最长路
题目链接 给一个n*m的图, 从0, 0这个点开始走,只能向右和向下. 图中有的格子有值, 求能获得的最大值. 其中有些格子可以传送到另外的格子, 有些格子不可以走. 将图中的每一个格子都看成一个点, ...
随机推荐
- iOS开发--Swift RAC响应式编程
时间不是很充足, 先少说点, RAC的好处是响应式编程, 不需要自己去设置代理委托, target, 而是主要以信息流(signal), block为主, 看到这里激动吧, 它可以帮你监听你的事件, ...
- 【译文】NginScript – 为什么我们要实现自己的JS引擎?
在上周的nginx.conf 2015用户大会上,我们发布了全新的JavaScript引擎nginscript的预览版.历史上,JavaScript语言已经应用在许多方面,首先是作为客户端脚本,然后又 ...
- EasyUIDataGrid 的List<T>转Json
EasyUI的DataGrid的Json自己拼接的话非常麻烦,而且容易出错,于是写了个通用的方法! CustomList<T>自定义类,继承于List<T>,用来处理返回的实体 ...
- 学习笔记4_ServletContext(重要整个Web应用的动态资源之间共享数据)
ServletContext(重要) 一个项目只有一个ServletContext对象! 我们可以在N多个Servlet中来获取这个唯一的对象,使用它可以给多个Servlet传递数据! 与天地同寿!! ...
- Linux 网络相关命令
1.修改ip,dns相关:sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0 2.ifconfig 查找ip,mac地址 3.重启网络:sudo ser ...
- 从客户端中检测到有潜在危险的 Request.Form 值] 处理办法
当asp.net提交<>这些字符到aspx页面时,如果未设置 validaterequest="false",就会出现错误:从客户端(<?xml version= ...
- JSP编程中常用的JavaScript技术(转载)
1.<tronMouseOver=this.style.backgroundColor=’#FFFFFF’ onMouseOut=this.style.backgroundColor=”> ...
- ajax详解,以及异步JSOP的实现
这里我使用的是jquery的ajax方法 包括三个方法 : get() , post(), getJson() get() 和post()的格式我就使用一下格式,很方便: $.ajax({ u ...
- JSTL之迭代标签库
JSTL之迭代标签库 JSTL的全称是 Java Server Pages Standard Tag Library,翻译过来就是JSP标准标签库,它包含了在开发JSP页面时经常用到的一组标准标签.这 ...
- html常用单词和各种少见标签
常用单词: 空格 align="left"valign="top"align="center"valign="middle&qu ...