1 3 2 1 2 1 3
2
#include<stdio.h>
#include<string.h>
#include<vector>
#include<string>
#include<iostream>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?b:a)
using namespace std;
int dfn[5050],low[5050],ins[5050],head[5050],belong[5050],stack[5050],link[5050];
int cnt,top,taj,time,n,m;
vector<int>vt[5050];
struct s
{
	int u,v,next;
}edge[100010*2];
void init()
{
	cnt=top=taj=time=0;
	memset(belong,-1,sizeof(belong));
	memset(ins,0,sizeof(ins));
	memset(low,-1,sizeof(low));
	memset(dfn,-1,sizeof(dfn));
	memset(head,-1,sizeof(head));
	memset(stack,0,sizeof(stack));
}
void add(int u,int v)
{
	edge[cnt].u=u;
	edge[cnt].v=v;
	edge[cnt].next=head[u];
	head[u]=cnt++;
}
void tarjin(int u)
{
	dfn[u]=low[u]=time++;
	stack[top++]=u;
	ins[u]=1;
	for(int i=head[u];i!=-1;i=edge[i].next)
	{
		int v=edge[i].v;
		if(dfn[v]==-1)
		{
			tarjin(v);
			low[u]=min(low[u],low[v]);
		}
		else
			if(ins[v])
				low[u]=min(dfn[v],low[u]);
	}
	if(dfn[u]==low[u])
	{
		taj++;
		int now;
		do
		{
			now=stack[--top];
			belong[now]=taj;
			ins[now]=0;
		}while(u!=now);
	}
}
int dfs(int u)
{
	for(int i=0;i<vt[u].size();i++)
	{
		int v=vt[u][i];
		if(!ins[v])
		{
			ins[v]=1;
			if(link[v]==-1||dfs(link[v]))
			{
				link[v]=u;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int i;
		init();
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++)
			vt[i].clear();
		while(m--)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			add(u,v);
		}
		for(i=1;i<=n;i++)
		{
			if(dfn[i]==-1)
			{
				tarjin(i);
			}
		}
		for(i=0;i<cnt;i++)
		{
			int u=edge[i].u;
			int v=edge[i].v;
			if(belong[u]!=belong[v])
			{
				vt[belong[u]].push_back(belong[v]);
			//	printf("%d %d %d %d\n",u,v,belong[u],belong[v]);
			}
		}
		memset(link,-1,sizeof(link));
		int ans=0;
		for(i=1;i<=taj;i++)
		{
			memset(ins,0,sizeof(ins));
			if(dfs(i))
				ans++;
		}
		printf("%d\n",taj-ans);
	}
}HDOJ题目3861 The King’s Problem(强连通,最小点覆盖)
原文:http://blog.csdn.net/yu_ch_sh/article/details/44175911