強連通分量縮點的模板

				        #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;
}                                                                        				    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章