POJ 2375 Cow Ski Area 增加最小边使图强连通

题意:一个矩阵图,每一个格子有一个权值,相邻格子之间可以通,条件是一个格子可以走到相邻格子的条件是相邻格子的全是不大于当前格子,问增加多少条边使得每一个格子都可以到达任意格子


想法:tarjan缩点,之后,结果为Max(出度为0点个数,入度为0点个数)
因为这个图,没有孤立点。

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdio>
#include<stack>
using namespace std;
const int N=250000+50;
const int M=2000000+50;
int w,l,n;
int map[505][505];
struct node
{
	int v,next;
}e[M];
stack<int>s;
int head[N],cnt;
int dfn[N],low[N],index,col,in[N],out[N],instack[N],paint[N];
void Init()
{
	while(!s.empty()) s.pop();
	memset(head,-1,sizeof(head));
	cnt=0;
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	memset(in,0,sizeof(in));
	memset(out,0,sizeof(out)); 
	memset(instack,0,sizeof(instack));
	memset(paint,0,sizeof(paint));
	col=index=0;
}
void add(int a,int b)
{
	e[cnt].v=b;
	e[cnt].next=head[a];
	head[a]=cnt++;
}
int Min(int a,int b)
{
	if(a<b) return a;
	return b;
}
void tarjan(int u)
{
	dfn[u]=low[u]=++index;
	instack[u]=1;
	s.push(u);
	for(int i=head[u];i+1;i=e[i].next)
	{
		int v=e[i].v;
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=Min(low[u],low[v]);
		}
		else if(instack[v])
		{
			low[u]=Min(low[u],dfn[v]);
		}
	}
	if(dfn[u]==low[u])
	{
		++col;
		int k=s.top();
		while(k!=u)
		{
			s.pop();
			instack[k]=0;
			paint[k]=col;
			k=s.top();
		}
		s.pop();
		instack[u]=0;
		paint[u]=col;
	}
}
int main()
{
	while(~scanf("%d%d",&w,&l))
	{
		n=w*l;
		Init();
		for(int i=1;i<=l;i++)
		{
			for(int j=1;j<=w;j++)
			{
				scanf("%d",&map[i][j]);
			}
		}
		for(int i=1;i<=l;i++)
		{
			for(int j=1;j<=w;j++)
			{
				int num=(i-1)*w+j;
				if(j+1<=w)
				{
					if(map[i][j]>map[i][j+1])
					{
						add(num,num+1);
					}
					else if(map[i][j]<map[i][j+1])
					{
						add(num+1,num);
					}
					else 
					{
						add(num,num+1);
						add(num+1,num);
					}
				}
				if(i+1<=l)
				{
					if(map[i][j]>map[i+1][j])
					{
						add(num,num+w); 
					}
					else if(map[i][j]<map[i+1][j])
					{
						add(num+w,num);
					}
					else 
					{
						add(num,num+w);
						add(num+w,num);
					}
				}
			}
		}
		for(int i=1;i<=n;i++)
		{
			if(!dfn[i]) tarjan(i);
		}
		for(int i=1;i<=n;i++)
		{
			for(int j=head[i];j+1;j=e[j].next)
			{
				int a=i,b=e[j].v;
				if(paint[a]!=paint[b])
				{
					out[paint[a]]++;
					in[paint[b]]++;
				}
			}
		}
		int inn=0,outn=0,res;
		for(int i=1;i<=col;i++)
		{
			if(!in[i]) inn++;
			if(!out[i]) outn++;
		}
		if(inn>outn) res=inn;
		else res=outn;
		if(col==1) printf("0\n");
		else printf("%d\n",res);
	}
	return 0;
} 

你可能感兴趣的:(POJ 2375 Cow Ski Area 增加最小边使图强连通)