HDU 2767 Proving Equivalences

题意:n个点 m条边(下面m行  a->b 表示单向边)

问:使图变成强连通需要增加几条边


思路:

把图变成树(树中每条边都是桥,再计算连通分支之间需要的边)

连通分支用tarjan缩点,然后统计连通分支的度(这里统计的方法有点暴力,可以用并查集统计)

补充:

桥:去掉桥后两边不连通(即 图去掉这条边后变成2块 的边 叫做桥)

连通分支: 上面说的块 就是连通分支

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define N 20010
int Low[N],dfn[N],stack[N],top,head[N];
bool Ins[N];
int F[N];
int Find(int x){if(x==F[x])return x;return F[x]=Find(F[x]);}
int en,time,kuai,K[N];//k[x] x点属于的块 kuai用来计数图中块的数量 time是遍历图的走的步数
struct node{
	int f,t,pre;
}edge[N*3];//en 是边数

inline int Min(int a,int b){return a>b?b:a;}
void add(int a,int b){
	edge[en].f=a,edge[en].t=b;edge[en].pre=head[a];
	head[a]=en;	en++;
}

void Tarjan(int u){
	dfn[u]=Low[u]=++time;
	stack[++top]=u;	Ins[u]=true;
	for(int i=head[u];i!=-1;i=edge[i].pre)
	{
		int v=edge[i].t;
		if(dfn[v]==-1)
		{
			Tarjan(v);
			Low[u]=Min(Low[u],Low[v]);
		}
		else if(Ins[v])
			Low[u]=Min(Low[u],dfn[v]);
	}
	if(Low[u]==dfn[u])
	{
		++kuai;	int v;
		do{
			v=stack[top--]; Ins[v]=false;
			K[v]=kuai;
			if(u<v)	F[u]=Find(F[v]);
			else    F[v]=Find(F[u]);
		}while(v!=u);
	}	
}
void Tsolve(int n){
	memset(dfn,-1,sizeof(dfn));
	time=top=kuai=0;
	for(int i=1;i<=n;i++)if(dfn[i]==-1)Tarjan(i);
}
int chudu[N],rudu[N];
int zouni(int n)
{
	if(kuai<=1)return 0;
	memset(chudu,0,sizeof(chudu));
	memset(rudu,0,sizeof(rudu));
	for(int i=1;i<=n;i++)
	{
		int u=K[i];
		for(int j=head[i];j!=-1;j=edge[j].pre)
		{
			int v=K[edge[j].t];	
			if(u!=v)
				chudu[v]++,rudu[u]++;
		}
	}
	int sum1 = 0,sum2 = 0;
    for (int i = 1; i <= kuai; i ++) if(!chudu[i]) sum1 ++;
    for (int i = 1; i <= kuai; i ++) if(!rudu[i]) sum2 ++;
    return sum1 > sum2 ? sum1 : sum2;
}
int main()
{
	int n,i,m,T;scanf("%d",&T);
	while(T--)
	{
		scanf("%d %d",&n,&m);
		en=0;		memset(head,-1,sizeof(head));
		for(i=1;i<=n;i++)F[i]=i;
		while(m--){	int a,b;scanf("%d%d",&a,&b);  add(a,b);}

		Tsolve(n);//共n个点(1-n)
		printf("%d\n",zouni(n));
	}
	return 0;
}
/*
99
5 5
1 2
2 3
3 4
4 1
1 3
ans:2

*/


你可能感兴趣的:(HDU 2767 Proving Equivalences)