#include<iostream>
#include<cstdio>
#include <cmath>
#include <vector>
#include <stack>
#include<cstring>
#include <algorithm>
using namespace std;
const int nMax=300;
const int mMax=9000005;
int n,m;
vector<int>mp[nMax];
stack<int>mystack;
bool cmp(int a,int b){return a>b;}
int dfn[nMax];
int low[nMax];
int vis[nMax];
int tmp;
int tp;
int cnt;
int now;
void tarjan(int u)
{
dfn[u]=low[u]=tmp;
tmp++;
vis[u]=1;
mystack.push(u);
for(int i=0;i<mp[u].size();i++)
{
int v=mp[u][i];
if(v==now)continue;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v])
{
low[u]=min(dfn[v],low[u]);
}
}
if(low[u]==dfn[u])
{
int v;
int s=0;
do
{
v=mystack.top();
mystack.pop();
vis[v]=0;
s++;
}while(v!=u);
if(s<2)s=0;
if(s>tp)
tp=s;
}
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
int u,v;
tmp=1;
cnt=0;
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
for(int i=1;i<=n;i++)
mp[i].clear();
while(!mystack.empty())
mystack.pop();
for(int i=0;i<m;i++)
{
cin>>u>>v;
u++;
v++;
mp[u].push_back(v);
}
int ans=99999;
for(int i=1;i<=n;i++)//枚举删掉的点
{
now=i;
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
while(!mystack.empty())
tmp=1;
tp=0;
int ttp=0;
for(int u=1;u<=n;u++)//因为图可能不是一个联通子图
{
tp=0;
if(!dfn[u]&&u!=now)
tarjan(u);
ttp=max(ttp,tp);
}
ans=min(ans,ttp);
}
cout<<ans<<endl;
}
return 0;
}
求图中去掉一个点,求剩余的最大的联通分量中的点的数量。
刚开始理解题目错了,以为是最大联通分量中去掉一个点剩余的最小联通分量有多少个点。晕。。。。懊悔当时没搞出来。模板题。