poj 3592 缩点+SPFA
来源:互联网 发布:ssd固态硬盘优化软件 编辑:程序博客网 时间:2024/06/11 13:24
题意:给出一个矩阵,其中#代表墙,不可走,0-9代表权值,*代表可以选择传送。求从0,0点开始出发能获得最大权值。
思路:因为*的出现会有环的情况,先建图连边,将环进行Tarjan缩点,之后再从0,0用SPFA找最长路就行了。
麻烦的地方在于建图,还有各种错
代码:
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define MAXN 1605#define MAXM 1605*1605#define inf 10000000int map[MAXN][MAXN],DFN[MAXN],Low[MAXN],vis[MAXN];int stack[MAXM],instack[MAXN],Belong[MAXN],a[MAXN],b[MAXN];int que[1605*MAXN],sign[1605*MAXN],dis[1605*MAXN],head[1605*MAXN],val[1605*MAXN];int G[MAXN][MAXN];char g[50][50];int kt,n,m,count1,scnt,top,tot;struct Edge{ int to,next;}edge[MAXM];void addedge(int v,int w){ edge[tot].to=w; edge[tot].next=head[v]; head[v]=tot++;}void SPFA(int s){ memset(sign,false,sizeof(sign)); for(int i=1;i<=scnt;i++) { dis[i]=0; } int l,r; l=r=0; que[r++]=s; sign[s]=true; dis[s]=val[s]; while(l!=r) { int v=que[l++]; sign[v]=true; for(int i=head[v];i!=-1;i=edge[i].next) { int j=edge[i].to; if(dis[j]<=dis[v]+val[j]) { dis[j]=dis[v]+val[j]; if(!sign[j]) { sign[j]=true; que[r++]=j; } } } sign[v]=false; }}void Tarjan(int v){ instack[v]=1; stack[top++]=v; DFN[v]=Low[v]=++count1; for(int i=0;i<n*m;i++) { if(map[v][i]==1) { if(!DFN[i]) { Tarjan(i); Low[v]=min(Low[v],Low[i]); } else if(instack[i]==1) { Low[v]=min(Low[v],DFN[i]); } } } int t; if(DFN[v]==Low[v]) { scnt++; do { t=stack[--top]; instack[t]=0; Belong[t]=scnt; }while(t!=v); }}void dfs(int x,int y){ vis[x*m+y]=1; if(g[x][y]=='#') return ; if(g[x][y]>='a'&&g[x][y]<='a'+kt) { int t=g[x][y]-'a'; if(!map[x*m+y][a[t]*m+b[t]]&&x*m+y!=a[t]*m+b[t]) { map[x*m+y][a[t]*m+b[t]]=1; if(!vis[a[t]*m+b[t]]) dfs(a[t],b[t]); } } if(x+1<n&&g[x+1][y]!='#') { if(!map[x*m+y][(x+1)*m+y]) { map[x*m+y][(x+1)*m+y]=1; if(!vis[(x+1)*m+y])dfs(x+1,y); } } if(y+1<m&&g[x][y+1]!='#') { if(!map[x*m+y][x*m+y+1]) { map[x*m+y][x*m+y+1]=1; if(!vis[x*m+y+1])dfs(x,y+1); } }}int main(){ int T; scanf("%d",&T); while(T--) { memset(g,'\0',sizeof(g)); scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%s",g[i]); } kt=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(g[i][j]=='*') { kt++; g[i][j]='a'+kt; } } } for(int i=1;i<=kt;i++) { scanf("%d%d",&a[i],&b[i]); } memset(map,0,sizeof(map)); memset(vis,0,sizeof(vis)); dfs(0,0); memset(DFN,0,sizeof(DFN)); memset(instack,0,sizeof(instack)); memset(stack,0,sizeof(stack)); memset(Low,0,sizeof(Low)); memset(Belong,0,sizeof(Belong)); count1=scnt=top=0; Tarjan(0); memset(val,0,sizeof(val)); for(int i=0;i<n*m;i++) { if(g[i/m][i%m]<='9'&&g[i/m][i%m]>='0') { val[Belong[i]]+=g[i/m][i%m]-'0'; } } tot=0; memset(head,-1,sizeof(head)); memset(G,0,sizeof(G)); for(int i=0;i<n*m;i++) { for(int j=0;j<n*m;j++) { if(map[i][j]&&Belong[i]!=Belong[j]) { if(!G[Belong[i]][Belong[j]]) { addedge(Belong[i],Belong[j]); G[Belong[i]][Belong[j]]=1; //cout<<Belong[i]<<','<<Belong[j]<<endl; } } } //cout<<Belong[i]<<' '; } SPFA(Belong[0]); int ans=0; for(int i=1;i<=scnt;i++) { if(dis[i]>ans) ans=dis[i]; } printf("%d\n",ans); } return 0;}/*1002 2***90 10 10 0*/
- poj 3592 缩点+SPFA
- poj 3592 Instantaneous Transference 【SCC +缩点 + SPFA】
- poj 3592 Instantaneous Transference tarjan缩点 最长路 ++tarjan模版 && spfa最长路模版
- poj 3592(强连连通分量+缩点+重建图形+spfa求最长路)
- POJ 3592--Instantaneous Transference【SCC缩点新建图 && SPFA求最长路 && 经典】
- Poj 3592 Instantaneous Transference【强连通Tarjan+染色缩点+SPFA】
- POJ 3592 Instantaneous Transference (强连通分量 缩点 spfa最长路)
- POJ 3592 强连通缩点+spfa最长路
- POJ 3592 强连通缩点+spfa最长路
- POJ 3160(缩点+spfa最长路+dp)
- poj 3114(强连通缩点+SPFA)
- POJ 3592 缩点加spfa
- poj3592 tarjan缩点+spfa
- bzoj1179 tarjan缩点+spfa
- POJ 3592 Instantaneous Transference 强连通缩点+spfa最长路
- poj 3114 Countries in War(强连通分量缩点+spfa求最短路)
- POJ 3160 Father Christmas flymouse tarjan缩点+spfa求最长路
- poj 3160 Father Christmas flymouse (SCC缩点+SPFA求最长路)
- struts.xml中自动提示
- DataGridView中的Combobox的应用
- 如何在远程桌面无响应的情况下完成远程电脑重启
- 德州扑克 信息
- 雷军:40岁重新再来 没什么大不了
- poj 3592 缩点+SPFA
- 一日一命令-屏幕文本编辑器Vi
- ubuntu-server-12.04.2访问virtualBox共享文件夹
- 字典树
- TerminateProcess结束进程
- 机器学习_hadoop探究_wordcount
- TCP报文格式详解
- Android 权限大全
- JNA java调用c/c++代码