分量入度hdu 3836 Equivalent Sets

最近研究分量入度,稍微总结一下,以后继续补充:

    hdu 2767 一样的目题

    求加几条边可以使原图成一个强连通分量

    思绪:先求出强连通分量个数,再求出每一个强连通分量的入度,度出

    入度为0的个数和度出为0的个数,最大的那个就是要加的边

 

 

 

 

 

 

    每日一道理
“上下五千年,龙的看火不灭;古有愚公志,而今从头越…… ”站在新世纪的门槛上,我们的追求就是让祖国灿烂的喜悦飞扬在美好的明天……
#include<stdio.h>

#include<stack>

#include<string.h>

using namespace std;

#define N 20001

#define inf 0x3fffffff

int n,m,OP;

int belong[N],dfs[N],low[N],ins[N],in[N],out[N];

struct op

{

	int end;

	struct op *next;

}*e[50002];

void addeage(int x,int y)

{

	struct op *q=new op;

	q->end=y;

	q->next=e[x];

	e[x]=q;

}

stack<int>Q;

int ans,idx;

void Tarjan(int x)

{

	int v;

	dfs[x]=low[x]=idx++;

	Q.push(x);

	ins[x]=1;

	for(op *j=e[x];j;j=j->next)

	{

		if(dfs[j->end]==-1)

		{

			Tarjan(j->end);

			low[x]=low[x]>low[j->end]?low[j->end]:low[x];

		}

		else if(ins[j->end]==1)

			low[x]=low[x]>dfs[j->end]?dfs[j->end]:low[x];

	}

	if(low[x]==dfs[x])

	{

		ans++;

		while(1)

		{

			v=Q.top();

			Q.pop();

			ins[v]=0;

			belong[v]=ans;

			if(v==x)break;

		}

		

	}

}

int main()

{

	int i,j,x,y,z,t;

	while(scanf("%d%d",&n,&m)!=-1)

	{

		OP=0;

		for(i=0;i<=n;i++)

		{

			e[i]=NULL;

			dfs[i]=-1;

			ins[i]=0;

			out[i]=0;

			in[i]=0;

		}

		for(i=0;i<m;i++)

		{

			scanf("%d%d",&x,&y);

			addeage(x,y);

		}

		ans=idx=0;

		for(i=1;i<=n;i++)

		{

			if(dfs[i]==-1)

				Tarjan(i);

		}

		if(ans==1)

		{

			printf("0\n");

			continue;

		}

		for(i=1;i<=n;i++)

		{

			for(op *j=e[i];j;j=j->next)

			{

				if(belong[i]!=belong[j->end])

				{

					in[belong[j->end]]++;

					out[belong[i]]++;

				}

			}

		}

		int OP1=0;

		for(i=1;i<=ans;i++)

		{

			if(in[i]==0)

				OP1++;

			if(out[i]==0)

				OP++;

		}

		if(OP<OP1)

			OP=OP1;

		printf("%d\n",OP);

	}

	return 0;

}

    
 

文章结束给大家分享下程序员的一些笑话语录: 自从有了Photoshop,我再也不相信照片了!(没有Photoshop的年代,胶片照片年代做假的也不少,那时候都相信假的!)

你可能感兴趣的:(set)