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)的更多相关文章

  1. POJ 3592 Instantaneous Transference(强连通+DP)

    POJ 3592 Instantaneous Transference 题目链接 题意:一个图.能往右和下走,然后有*能够传送到一个位置.'#'不能走.走过一个点能够获得该点上面的数字值,问最大能获得 ...

  2. POJ 2186 Popular Cows(强联通分量)

    题目链接:http://poj.org/problem?id=2186 题目大意:    每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种 ...

  3. POJ 2186-Popular Cows (图论-强联通分量Korasaju算法)

    题目链接:http://poj.org/problem?id=2186 题目大意:有n头牛和m对关系, 每一对关系有两个数(a, b)代表a牛认为b牛是“受欢迎”的,且这种关系具有传递性, 如果a牛认 ...

  4. 强联通分量-tarjan算法

    定义:在一张有向图中,两个点可以相互到达,则称这两个点强连通:一张有向图上任意两个点可以相互到达,则称这张图为强连通图:非强连通图有极大的强连通子图,成为强联通分量. 如图,{1},{6}分别是一个强 ...

  5. [vios1023]维多利亚的舞会3<强联通分量tarjan>

    题目链接:https://vijos.org/p/1023 最近在练强联通分量,当然学的是tarjan算法 而这一道题虽然打着难度为3,且是tarjan算法的裸题出没在vijos里面 但其实并不是纯粹 ...

  6. poj 3592 Instantaneous Transference 【SCC +缩点 + SPFA】

    Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6204   Accep ...

  7. POJ 3114 Countries in War(强联通分量+Tarjan)

    题目链接 题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0. 思路 :强连通分量缩点之后,求最短路.以前写过,总感觉记忆不深,这次自己敲完再写了一遍. #include ...

  8. poj 3592 Instantaneous Transference

    http://poj.org/problem?id=3592 #include <cstdio> #include <cstring> #include <algorit ...

  9. poj 3592 Instantaneous Transference 缩点+最长路

    题目链接 给一个n*m的图, 从0, 0这个点开始走,只能向右和向下. 图中有的格子有值, 求能获得的最大值. 其中有些格子可以传送到另外的格子, 有些格子不可以走. 将图中的每一个格子都看成一个点, ...

随机推荐

  1. 理解JavaScript原型式继承

    0.基础 javascript没有类的概念, javascript不需要实例化某个具体类的实例.javascript对象本身可以用来创建对象, 而对象可以继承自其他对象, 这个概念称为原型式继承 每个 ...

  2. IO流详解(半教材类型)

    这两天学习了IO流,整理了一些理论知识点,仅供参考. java流概述 一 流 从操作系统层面和文件系统,数据保存相关的是所有语言都具备的一个基本功能,java专门开发了一个包:java.io.*;ja ...

  3. Java编程思想读书笔记--第14章类型信息

    7.动态代理 代理是基本的设计模式之一,它是你为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象.这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色. 什么是代理模式? ...

  4. android 登陆案例_sd卡

    代码: <?xml version="1.0"?> -<LinearLayout android:paddingTop="@dimen/activity ...

  5. Java实战之04JavaWeb-07Listener和Filter

    一.监听器Listener javaEE的13们规范中 包括servlet技术和jsp技术 servlet规范中包括三门技术:(servlet的三大组件) servelt技术  Listener技术 ...

  6. 原子/Atomic操作

    原子/Atomic操作 一.什么是 原子/atom   这个术语用原子来表示不够准确,原子翻译自atom/atomic,其中atom在词典中的「词源/etymology」是: [Middle Engl ...

  7. [翻译][MVC 5 + EF 6] 9:异步和存储过程

    原文:Async and Stored Procedures with the Entity Framework in an ASP.NET MVC Application 1.为什么使用异步代码: ...

  8. angular中的orderBy过滤器使用

    一  orderBy过滤器   AngularJS中orderBy进行排序,第一个参数可以有三种类型,分别为:function,string,array:   第一种:function,如果是func ...

  9. ubuntu12修改ulimit

    第一步:配置/etc/security/limits.confsudo vim /etc/security/limits.conf文件尾追加 * hard nofile 40960* soft nof ...

  10. App开发中甲乙方冲突会闹出啥后果?H5 APP 开发可以改变现状吗

    随着各种应用的全面App化,因App而起的合作纠纷也日益增多,其中不乏最终对簿公堂的情形.WeX5(html5开发工具)为您汇总了三个典型的真实案例,方便您体会甲乙方冲突情景. 在围观别人争吵之余,您 ...