题意:

  给一个矩形,矩形中某些点有一定数量的矿石,有些点为传送点,有些点为障碍。你驾驶采矿车(ore-miner truck,我也不知道是什么),从左上角出发,采尽量多的矿石,矿石不可再生。不能往左边或者上面走。传送点可以往左边或上面传。2<=n,m<=40

分析:

  可以把矩形看作一张图,每个格子为一个点,每个格子与它右边和下面的点连接一条有向边。每个传送点与它传送的位置连接一条有向边。如果右边或下面为#那么不连。值得注意的是题目并没有保证传送点传送到的一定不是#,所以需要进行判断。

   这样,我们得到了一个点数|V|=n*m,边数最大|E|=O(n*m)的有向有环图。答案就是限制只能取一次的最长路。

  我们现在的任务就是把只能取一次抽象成另一种能实现的东西,不然暴力是指数级的。

  很显然,向后传送不需要考虑,只考虑传回前面,在图上的表现为成环,或者说同属一个强连通分量。

  很自然地就可以发现同属一个强连通分量的点都可以同时取到,我们考虑用tarjan缩点,这样建的就是一个DAG,在这个DAG上跑最长路,就是答案。

   这里值得一提的是,这里不能用dijkstra,同时我们可以下结论:求最长路时,dijkstra算法只适用于负权图,求最短路时,dijkstra算法只适用于正权图。所以这里要写SPFA。

代码:用emacs写的,所以不要吐槽两格缩进

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cstring>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
int low[],dfn[],arr[],scc[],al,cl,w[];
vector<int> g[];
vector<int> ng[];
stack <int> sta;
void tarjan(int now){
low[now]=dfn[now]=++cl;
sta.push(now);
for(int i=;i<g[now].size();i++){
int k=g[now][i];
if(arr[k])continue;
if(!dfn[k]){
tarjan(k);
low[now]=min(low[now],low[k]);
}else
low[now]=min(low[now],dfn[k]);
}
if(low[now]==dfn[now]){
al++;
while(){
int u=sta.top();
sta.pop();
arr[u]=;
scc[u]=al;
if(u==now) break;
}
}
}
int a[][];
void readint(int n,int m){
memset(arr,,sizeof(arr));
memset(w,,sizeof(w));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(scc,,sizeof(scc));
al=cl=;
for(int i=;i<=n*m;i++)g[i].clear(),ng[i].clear();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
char x;cin>>x;
if(x=='*')a[i][j]=;
else
if(x=='#')a[i][j]=-;
else a[i][j]=(int)(x-);
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(j+<=m&&a[i][j+]!=-)g[i*m-m+j].push_back(i*m-m+j+);
if(i+<=n&&a[i+][j]!=-)g[i*m-m+j].push_back(i*m+j);
if(a[i][j]==){
int x,y;cin>>x>>y;
if(a[x+][y+]==-)continue;
else g[i*m-m+j].push_back(x*m+y+);
}
}
}
}
void dij(int n){//SPFA找最长路
queue <int> que;
int dist[];
memset(dist,,sizeof(dist));
dist[scc[]]=w[scc[]];
que.push(scc[]);
while(!que.empty()){
int k=que.front();
for(int i=;i<ng[k].size();i++){
if(dist[k]+w[ng[k][i]]>dist[ng[k][i]]){
dist[ng[k][i]]=dist[k]+w[ng[k][i]];
que.push(ng[k][i]);
}
}
que.pop();
}
int maxx=;
for(int i=;i<=n;i++)maxx=max(maxx,dist[i]);
cout<<maxx<<endl;
} int main(){
int t;cin >> t;
while(t--){
int n,m;
cin>>n>>m;
readint(n,m);
for(int i=;i<=n*m;i++)
if(!arr[i])
tarjan(i);//求强连通分量
for(int i=;i<=n*m;i++){
for(int j=;j<g[i].size();j++){
if(scc[i]==scc[g[i][j]])continue;
ng[scc[i]].push_back(scc[g[i][j]]);
}
}//缩点
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(a[i][j]==-||a[i][j]==)continue;
w[scc[i*m-m+j]]+=a[i][j];
}
}//算新的点权
dij(al);//求最长路
}
return ;
111 }

  

POJ3592 Instantaneous Transference题解的更多相关文章

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

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

  2. POJ3592 Instantaneous Transference tarjan +spfa

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

  3. poj3592 Instantaneous Transference tarjan缩点+建图

    //给一个n*m的地图.坦克从(0 , 0)開始走 //#表示墙不能走,*表示传送门能够传送到指定地方,能够选择也能够选择不传送 //数字表示该格的矿石数, //坦克从(0,0)開始走.仅仅能往右和往 ...

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

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

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

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

  6. POJ 3592 Instantaneous Transference(强联通分量 Tarjan)

    http://poj.org/problem?id=3592 题意 :给你一个n*m的矩阵,每个位置上都有一个字符,如果是数字代表这个地方有该数量的金矿,如果是*代表这个地方有传送带并且没有金矿,可以 ...

  7. poj 3592 Instantaneous Transference

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

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

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

  9. Instantaneous Transference(强连通分量及其缩点)

    http://poj.org/problem?id=3592 题意:给出一个n*m的矩阵,左上角代表起始点,每个格子都有一定价值的金矿,其中‘#’代表岩石不可达,‘*’代表时空门可以到达指定格子,求出 ...

随机推荐

  1. XML入门知识

    什么是XML? 答:指可扩展标记语言(eXtensible Markup Language),被设计用来传输和存储数据:标签没有被预定义.您需要自行定义标签:被设计为具有自我描述性. XML和HTML ...

  2. js:如何在循环异步请求的每次返回中添加想要的值

    先看一个场景 var arr = ["a","b","c"]; for (var i in arr) {         $.get(&qu ...

  3. iOS回顾笔记( 02 ) -- 由九宫格布局引发的一系列“惨案”

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  4. 第十九篇 js高级知识---词法分析和AO 链

    上面一篇文章说了js的作用域链,这一节算是对上面的延申,有一个典型的例子,首先看原来的一段代码: var name = "test"; function t() { var b = ...

  5. 【openstack N版】——云主机调整大小\冷迁移

    一.先决条件 云主机冷迁移,即:将一台云主机从一个计算节点上,迁移到另外一个计算节点上.因为环境原因,所以我们需要准备两个计算节点. 1.1准备环境 在控制节点上,安装一个计算节点 #在控制节点安装n ...

  6. C#中判断字符串相等的方法

    可以使用如下方式: 1. String.Compare(str1, str2) == 0  或者  str1.CompareTo(str2) == 0 2. str1.Equals(str2)  或者 ...

  7. debian+nginx配置初探--php环境、反向代理和负载均衡

    配置nginx的PHP环境 安装nginx sudo apt-get install nginx 安装nginx就可以通过下面地址来访问了:http://localhost/ 安装php sudo a ...

  8. MySQL中的完整性约束条件(主键、外键、唯一、非空)

    数据库的完整性约束用来防止对数据的意外破坏,来保证数据的安全性和一致性. 主键 1.创建表时候指定主键 创建表user(id, username, age),并且id字段非空自增. CREATE TA ...

  9. [OpenGL] mac上运行NateRobin的OpenGL教程找不到 data file 解决方案

    之前买的OpenGL编程指南第七版一直没看,最近开始看了,然后按照教程推荐的去指定网址下载NateRobin的OpenGL教程,但发现网址已经提示Error:404了, 然后谷歌搜索到可用的下载网址为 ...

  10. Vue学习之路---No.5(分享心得,欢迎批评指正)

    同样,首先我们还是回顾一下昨天讲到的东西: 1.常用的Vue修饰器 2.当利用js方法不修改数据,但也可以改变视图时,我们需要整体返回再整体接收 (如: items.example1 = items. ...