poj 2375 (强连通分量缩点max(入度,出度))



题意:给定一个滑雪场,每个点能向周围4个点高度小于等于这个点的点滑,现在要建电缆,使得任意两点都有路径互相可达,问最少需要几条电缆

思路:强连通缩点,每个点就是一个点,能走的建边,缩点后找入度出度为0的个数的最大值就是答案,注意一开始就强连通了答案应该是0


#include
#include
#include
#include
#include
#include
#include
#include 
#include
#include
using namespace std ;
const int N= 300000 ;
const int M= 2222222 ;
const int dx[] = {-1, 1, 0, 0};  
const int dy[] = {0, 0, -1, 1}; 
struct node
{
	int  u ,  v , next ;
}edge[M] ;
int head[N],vist[N],low[N],dfn[N],belong[N],stack[N],g[505][505] ,out[N],in[N];
int top , sum , cnt , dep , n,m ;

int cheak(int i , int  j)
{
	 if( i >= 0 && i < n && j >= 0 && j= g[xx][yy])
			    	  	    {
			    	  	    	   add(u,v);w++;
			    	  	    }
			    	  	    if(g[i][j] <= g[xx][yy])
			    	  	    {
			    	  	    	  add(v,u);w++;
			    	  	    }
			    	  }
			    }      
	  	  //  printf("%d\n",w);
		    for(int i = 0 ; i < n*m ; i++)
			      if(!dfn[i])
			        tarjan(i) ;
		 //   	printf("*%d* ",sum);
			for(int i = 0 ; i < n*m ; i++)
			  for(int j= head[i] ; j!=-1; j=edge[j].next)
			    {
			    	   int v = edge[j].v ; 
			    	   if(belong[i] != belong[v])
					   {
					      in[belong[v]]++ ;
					      out[belong[i]]++;
				       }
			    } 	
			if(sum <= 1 )    //刚开始强联通的    
			   printf("0\n") ;
			else
			{
				   int a=0,b=0;
				   for(int i = 1 ; i <= sum ; i++)
				    {
				      if(out[i] == 0)
				         a++ ;
				       if(in[i] == 0)
					     b++ ;   
				    }
				    printf("%d\n",max(a,b)) ;
			}    
			         
	  }
	return 0;
} 





你可能感兴趣的:(强联通图)