传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3836
http://acm.hdu.edu.cn/showproblem.php?pid=2767
#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
int n , cnt , index , sum;
const int size = 120010;
struct data
{
int st;
int end;
}node[size*3];
struct graph
{
int to;
int next;
}edge[size*3];
int head[size];
int father[size]; //low[]
int No[size]; //dfn[]
int scc[size];
int in[size];
int out[size];
bool vis[size];
stack<int>s;
void init( )
{
memset( head , -1 , sizeof(head) );
memset( No , 0 , sizeof(No) );
memset( father , 0 , sizeof(father) );
memset( vis , false , sizeof(vis) );
memset( scc , 0 , sizeof(scc) );
memset( in , 0 , sizeof(in) );
memset( out , 0 , sizeof(out) );
}
void add( int st , int end )
{
edge[cnt].to = end;
edge[cnt].next = head[st];
head[st] = cnt ++;
}
void tarjan( int u )
{
int v , temp;
No[u] = father[u] = index++;
vis[u] = true;
s.push(u);
for( int i = head[u] ; ~i ; i = edge[i].next )
{
v = edge[i].to;
if( !No[v] )
{
tarjan(v);
father[u] = min( father[u] , father[v] );
}
else if( vis[v] )
{
father[u] = min( father[u] , No[v] );
}
}
if( father[u] == No[u] )
{
sum ++; //缩点操作
while(1)
{
temp = s.top();
s.pop();
vis[temp] = false;
scc[temp] = sum;
if( father[temp] == No[temp] )
break;
}
}
}
int main()
{
cin.sync_with_stdio(false);
int m , st , end , inMax , outMax;
while( cin >> n >> m )
{
inMax = outMax = cnt = sum = 0;
index = 1;
init();
for( int i = 0 ; i<m ; i++ )
{
cin >> st >> end;
add( st , end );
node[i].st = st;
node[i].end = end;
}
for( int i = 1 ; i<=n ; i++ )
{
if( !No[i] )
tarjan(i);
}
for( int i = 0 ; i<m ; i++ )
{
if( scc[ node[i].st ]!=scc[ node[i].end ] )
//如果起点终点不在同一个联通块里,起点所在联通块出度++ ,终点的入度++
{
out[ scc[node[i].st] ] ++;
in[ scc[node[i].end] ] ++;
}
}
//记录联通块出入度时, 还可以有别的方法, 如遍历所有点, 访问其邻接表里的与之相连的点
//当然也可以邻接矩阵的访问方法时间是n^2
for( int i = 1 ; i<=sum ; i++ )
{
//计算出度与入度为 0 的点数量
if( !in[i] )
inMax ++;
if( !out[i] )
outMax ++;
}
if( sum==1 ) //特殊处理只有 1 个联通块的情况
cout << "0" << endl;
else
cout << max( inMax , outMax ) << endl;
}
return 0;
}