#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
using namespace std;
#define inti(a) memset(a,0,sizeof(a))
#define min(a,b) ((a)>(b)?(b):(a))
#define max(a,b) ((a)>(b)?(a):(b))
const int Max=1605;
const int inf=1000000000;
typedef struct sdlf
{
int self;
int son;
int next;
}Edge;
Edge edge[2][5000];
int dfsnum[Max],low[Max],stack[Max],top,cnt,tag,head[2][Max];
bool flag[Max];
char maze[45][45];
int n,m,w[Max],d[Max],belong[Max],Enum;
void insert(int u,int v,int h)
{
edge[h][Enum].self=u;
edge[h][Enum].son=v;
edge[h][Enum].next=head[h][u];
head[h][u]=Enum++;
}
bool judge(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<m&&maze[x][y]!='#')return true;
return false;
}
void read()
{
int i,j;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%s",maze[i]);
Enum=0;
memset(head,-1,sizeof(head));
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
int u=i*m+j;
if(isdigit(maze[i][j]))
{
if(judge(i+1,j))
insert(u,u+m,0);
if(judge(i,j+1))
insert(u,u+1,0);
maze[i][j]-=48;
}
else if(maze[i][j]=='*')
{
int a,b;
scanf("%d%d",&a,&b);
insert(u,a*m+b,0);
maze[i][j]=0;
if(judge(i+1,j))
insert(u,u+m,0);
if(judge(i,j+1))
insert(u,u+1,0);
}
else maze[i][j]=0;
}
}
void DFS(int u)
{
dfsnum[u]=low[u]=++tag;
stack[top++]=u;
flag[u]=1;
for(int i=head[0][u];i!=-1;i=edge[0][i].next)
{
int v=edge[0][i].son;
if(!dfsnum[v])
{
DFS(v);
low[u]=min(low[u],low[v]);
}
else if(flag[v])low[u]=min(low[u],dfsnum[v]);
}
if(dfsnum[u]==low[u])
{
int x;
cnt++;
do{
x=stack[--top];
belong[x]=cnt;
flag[x]=0;
w[cnt]+=maze[x/m][x%m];
}while(x!=u);
}
}
void Tarjan()//求強聯通分量
{
inti(dfsnum);
inti(low);
inti(flag);
inti(w);
tag=cnt=top=0;
for(int i=0;i<n*m;i++)
if(!dfsnum[i])
DFS(i);
}
void Rebuild()//縮點建新圖
{
Enum=0;
int t=n*m;
for(int u=0;u<t;u++)
{
for(int i=head[0][u];i!=-1;i=edge[0][i].next)
{
int v=edge[0][i].son;
if(belong[u]!=belong[v])
insert(belong[u],belong[v],1);
}
}
}
int treedp(int u)//正常
{
if(head[1][u]==-1)return d[u]=w[u];
if(d[u]>=0)return d[u];
int sum=0;
for(int i=head[1][u];i!=-1;i=edge[1][i].next)
{
int v=edge[1][i].son;
int t=treedp(v);
sum=max(sum,t);
}
return d[u]=sum+w[u];
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
read();
Tarjan();
Rebuild();
memset(d,-1,sizeof(d));
printf("%d\n",treedp(belong[0]));
}
return 0;
}
強連通分量縮點的模板
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.