POJ 3592 Instantaneous Transference
来源:互联网 发布:matlab数据拟合工具箱 编辑:程序博客网 时间:2024/05/16 14:10
题目大意:
给出一个n*m的格子地图,每一格上面是0~9,“*”或“#”。如果格子上是数字代表这个格子上有当前数量的矿石。如果是“*” 代表着当前格子是一个传送阵可以传送到指定的地方。如果是“#”代表当前格子不可达。
现在有一个矿车在坐标(0,0),也就是左上角。他只能向右和下行驶。当遇到传送阵时可以被传送到指定的位置。当他遇到数字时就可以得到那些数量的矿石,那个地方的矿石数量就变为“0”。问矿车最多可以采多少矿。
解题思路:
1、我们先要根据格子地图建图。(注1)
2、因为建立出的图可能会有环,我们要用Tarjan算法将环缩成点。(注2)
3、我们将缩点处理后的图重新建图。(注3)
4、对图求最长路。
注意:
1、要注意到“#”和从“#”出发的边是不建立的。当从“*”出发时需要建三条边:右,下,指定位置。
2、根据题意,经过的地方将不再有矿石。所以将环缩成点是最好的选择。因为如果可以到环中的任意一点,其他点也就可以到了。
3、重新建图的目的是为后来更容易的求最长路做准备。建图时对于每一条边(u,v),边的权值是点v所在的缩点的总权值。
4、求完最长路后得出的数值一定要再加上点0所在的缩点的总权值。
5、注意不要手残(手残毁一天啊~~~ T _ T ).
下面是代码:
#include <stdio.h>#include <string.h>#include <queue>using namespace std;const int MAXN = 2005;struct node{ int u,to,next;} edge[MAXN*10];struct node1{ int v,w,next;} newedge[MAXN*10];int n,m,p;int dfn[MAXN],low[MAXN],vis[MAXN],head[MAXN],stack1[MAXN],top,cnt,time;int num[MAXN],numcnt,numw[MAXN],map1[MAXN];int newhead[MAXN],newcnt;int dis[MAXN];char s[45][45];void init(){ memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); memset(newhead,-1,sizeof(newhead)); memset(numw,0,sizeof(numw)); memset(stack1,-1,sizeof(stack1)); memset(num,-1,sizeof(num)); top=0; cnt=0; newcnt=0; time=1; numcnt=0;}int min(int a,int b){ if(a>b)a=b; return a;}void addedge(int u,int v){ edge[cnt].u=u; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; cnt++;}void Buildedge(){ int x,y; for(int i=0; i<n; i++) { scanf("%s",s[i]); } for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(s[i][j]=='*') { scanf("%d%d",&x,&y); if(s[x][y]!='#') addedge(i*m+j,x*m+y); map1[i*m+j]=0; if(i+1<n&&s[i+1][j]!='#') { addedge(i*m+j,(i+1)*m+j); } if(j+1<m&&s[i][j+1]!='#') { addedge(i*m+j,i*m+j+1); } } else if(s[i][j]!='#') { map1[i*m+j]=s[i][j]-'0'; if(i+1<n&&s[i+1][j]!='#') { addedge(i*m+j,(i+1)*m+j); } if(j+1<m&&s[i][j+1]!='#') { addedge(i*m+j,i*m+j+1); } } else { map1[i*m+j]=0; } } }}void dfs(int u,int fa){ dfn[u]=time; low[u]=time; time++; vis[u]=1; stack1[top]=u; top++; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].to; if(!vis[v]) { dfs(v,u); low[u]=min(low[u],low[v]); } else if(vis[v]==1) { low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]) { while(stack1[top]!=u&&top>0) { top--; num[stack1[top]]=numcnt; vis[stack1[top]]=2; numw[numcnt]+=map1[stack1[top]]; } numcnt++; }}void addedgenew(int u,int v){ for(int i=newhead[u]; i!=-1; i=newedge[i].next) { if(newedge[i].v==v)return; } newedge[newcnt].v=v; newedge[newcnt].w=numw[v]; newedge[newcnt].next=newhead[u]; newhead[u]=newcnt; newcnt++;}int spfa(int src){ queue <int> q; q.push(src); memset(vis,0,sizeof(vis)); vis[src]=true; for(int i=0; i<=numcnt; i++) { dis[i]=-1; } dis[src]=0; while(!q.empty()) { int p,t=q.front(); q.pop(); p=newhead[t]; vis[t]=false; while(p!=-1) { if(dis[newedge[p].v]<dis[t]+newedge[p].w) { dis[newedge[p].v]=dis[t]+newedge[p].w; if(!vis[newedge[p].v]) { vis[newedge[p].v]=true; q.push(newedge[p].v); } } p=newedge[p].next; } } int max1=0; for(int i=0; i<numcnt; i++) { if(dis[i]>max1) { max1=dis[i]; } } return max1+numw[src];}void Tarjan(){ for(int i=0; i<p; i++) { if(!vis[i])dfs(i,-1); }}void BuildAgain(){ for(int i=0; i<p; i++) { for(int j=head[i]; j!=-1; j=edge[j].next) { if(num[i]!=num[edge[j].to]&&num[i]!=-1&&num[edge[j].to]!=-1) { addedgenew(num[i],num[edge[j].to]); } } }}int main(){ int t; scanf("%d",&t); while(t--) { init(); scanf("%d%d",&n,&m); Buildedge();//建图 p=n*m; //总点数 Tarjan();//求强连通分量用来缩点 BuildAgain();//重新建图 printf("%d\n", spfa(num[0]));//求最长路 } return 0;}
0 0
- POJ 3592 Instantaneous Transference
- POJ 3592 Instantaneous Transference
- POJ 3592 Instantaneous Transference
- poj 3592 Instantaneous Transference
- POJ 3592 Instantaneous Transference
- poj 3592 Instantaneous Transference
- Poj 3592 Instantaneous Transference
- poj 3592 Instantaneous Transference
- POJ 3592 Instantaneous Transference
- Poj 3592 Instantaneous Transference
- POJ 3592 Instantaneous Transference Tarjan+SPFA
- POJ-3592-Instantaneous Transference 解题报告
- POJ--3592[Instantaneous Transference] 缩点+求最长路
- POJ 3592 Instantaneous Transference 强连通分量+缩点+DP
- POJ 3592 Instantaneous Transference(建图+缩点)
- poj 3592 Instantaneous Transference 强连通+缩点+最长路
- poj 3592 Instantaneous Transference(强连通+最长路)
- poj 3592 Instantaneous Transference(强连通分量+dp)
- Android权限Uri.parse的详细资料
- 读书笔记:“集体智慧编程”之第七章:决策树
- Java 学习笔记
- LeetCode 151道题分类+详细解答
- SQLite 安装使用
- POJ 3592 Instantaneous Transference
- JSON
- angularJS
- LoadLibrary方式加载DLL模版代码
- Ubuntu安装google-chrome浏览器
- jbpmEL表达式jar冲突
- 软件行业职位英文缩写介
- LibSVM 在matlab中的使用
- servlet过滤器详解