condensing point tarjan
Condensing point is used in graph theory techniques, when having a conductive path contribution, it may be a new strongly connected components shrink to a point, because the points within a strongly connected component can reach each other. The number of points within a strongly connected components can be stained by recording, with the same number of points is the color of the number of points in the strongly connected component.
Example: poj2186 Popular Cows
Tell your cattle have n, m a relationship of worship, and worship is transitive, if a worship b, b worship c, then a worship c, several cows have been seeking finally all cattle worship.
Sample Input
3 3
1 2
2 1
2 3
Sample Output
1
answer:
When the entire first consider the case of FIG acyclic (DAG), and when there is a cow worship all cattle, to consider only the number of point 0 (the degree of a certain number of points greater than or equal to 0 1), if it is 1, then a solution, if greater than 1, no solution;
if there FIG ring, then after a tarjan FIG identify strongly connected component, the point for point v u connected if their colors the same, they are described in the same strongly connected component, considered u, v in a super point, not shown in the statistics of u; if they are different in color, then these two points belong to different strongly connected components , can be added so that the degree of u 1.
statistics at completion, for each color (i.e., all strongly connected components) statistical point of 0 degree, to obtain the number of worship all cow "super-point." Note that the "super spot" If the point is greater than 1 points strongly connected component of the configuration, will have the number of points in the strongly connected component added answers, plus 1 instead.
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
int n,m;
const int maxn=10010;
int dfn[maxn],low[maxn],cnt[maxn],color[maxn],degree[maxn],vis[maxn];
int tot;
int st[maxn],top;
int tmp,ans;
int deep;
vector<int> g[maxn];
void tarjan(int u)
{
dfn[u]=++deep;
low[u]=deep;
vis[u]=1;
st[++top]=u;
int sz=g[u].size();
for(int i=0;i<sz;i++)
{
int v=g[u][i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else
{
if(vis[v])
low[u]=min(low[u],low[v]);
}
}
if(dfn[u]==low[u])
{
color[u]=++tot;
vis[u]=0;
while(st[top]!=u)
{
color[st[top]]=tot;
vis[st[top--]]=0;
}
top--;
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
memset(color,0,sizeof(color));
memset(degree,0,sizeof(degree));
memset(low,0,sizeof(low));
memset(cnt,0,sizeof(cnt));
memset(st,0,sizeof(st));
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
g[x].push_back(y);
}
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int i=1;i<=n;i++)
{
int sz=g[i].size();
for(int j=0;j<sz;j++)
{
int v=g[i][j];
if(color[i]!=color[v])
degree[color[i]]++;
}
cnt[color[i]]++;
}
for(int i=1;i<=tot;i++)
if(degree[i]==0) tmp++,ans=cnt[i];
if(tmp>1) printf("0\n");
else printf("%d\n",ans);
}
return 0;
}