标签:
强连通分量的求解,虽说第一眼一看数据量就知道能用Floyd写,但是谁让我太渣呢,还是别偷懒了。熟悉下tarjan。
/*
ID: modengd1
PROG: schlnet
LANG: C++
*/
#include <iostream>
#include <stdio.h>
#include <vector>
#include <stack>
#include <memory.h>
using namespace std;
bool vis[101];
bool insatck[101];
vector<int> G[101];
int N;
int dfn[101];
int low[101];
stack<int> ST;
int index;
int colored[101];
int color;
int newG[101][101];
void tarjan(int u)
{
vis[u]=true;
low[u]=dfn[u]=++index;
ST.push(u);
insatck[u]=true;
for(int i=0;i<G[u].size();i++)
{
if(!vis[G[u][i]])
{
tarjan(G[u][i]);
low[u]=min(low[G[u][i]],low[u]);
}
else if(insatck[G[u][i]])
{
low[u]=min(low[u],dfn[G[u][i]]);
}
}
if(low[u]==dfn[u])//同一个联通分量中的点染成一个颜色
{
color++;
while(ST.top()!=u)
{
colored[ST.top()]=color;
insatck[ST.top()]=false;
ST.pop();
}
colored[ST.top()]=color;
insatck[ST.top()]=false;
ST.pop();
}
}
void buildnew()
{
memset(newG,false,sizeof(newG));
for(int i=1;i<=N;i++)
{
for(int j=0;j<G[i].size();j++)
{
if(colored[i]!=colored[G[i][j]])
newG[colored[i]][colored[G[i][j]]]=true;
}
}
int cterO[101],cterI[101];
memset(cterO,0,sizeof(cterO));
memset(cterI,0,sizeof(cterI));
for(int i=1;i<=color;i++)
{
for(int j=1;j<=color;j++)
{
if(newG[i][j])
{
cterO[i]++;
cterI[j]++;
}
}
}
int ans0=0,ans1=0;
for(int i=1;i<=color;i++)
{
if(cterI[i]==0)//入度为零的点的个数
ans0++;
if(cterO[i]==0)//出度为零的点的个数
ans1++;
}
if(color==0)
{
cout<<1<<endl<<0<<endl;
}
else
{
cout<<ans0<<endl<<max(ans0,ans1)<<endl;
}
}
int main()
{
freopen("schlnet.in","r",stdin);
freopen("schlnet.out","w",stdout);
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
int v;
while(scanf("%d",&v)&&v!=0)
{
G[i].push_back(v);
}
}
index=0;
color=0;
memset(colored,0,sizeof(color));
for(int i=1;i<=N;i++)
{
if(colored[i]==0)
tarjan(i);
}
buildnew();
return 0;
}
标签:
原文地址:http://www.cnblogs.com/modengdubai/p/4859921.html