您的位置:首页 > 其它

bzoj 1051: [HAOI2006]受欢迎的牛

2014-01-06 18:50 399 查看
tarjan强连通分量求缩点重构图,出度为0的点若只有一个则输出其代表强连通分量的大小,否则无解。

因为一旦出度为0就没人被他认为长得帅

/*
ID:WULALA
PROB:bzoj1051
LANG:C++
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <fstream>
#include <ctime>
#define N 10008
#define M 50008
#define mod
#define mid(l,r) ((l+r) >> 1)
#define INF 0x7ffffff
using namespace std;

int n,m,dfn
,low
,que
,head
,cnt,h
,scc,belong
,ans,hav
,r;
bool vis
,inq
,flag;

struct WULALA
{
int node,next;
}e[M],d[M];

void init()
{
scanf("%d%d",&n,&m);
for (int i = 1;i <= m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
e[i].node = y;
e[i].next = head[x];
head[x] = i;
}
}

void dfs(int a)
{
vis[a] = true;
low[a] = dfn[a] = ++cnt;
inq[a] = true; que[++r] = a;
int c = head[a];
while(c)
{
if (!vis[e[c].node])
{
dfs(e[c].node);
low[a] = min(low[a],low[e[c].node]);
}
else if (inq[e[c].node]) low[a] = min(low[a],dfn[e[c].node]);//要判是否在队列里!!
c = e[c].next;
}
if (low[a] == dfn[a])
{
belong[a] = ++scc;
hav[scc] = 1;
while (que[r] != a)
{
belong[que[r]] = scc;
inq[que[r]] = false;
++hav[scc];
--r;
}
inq[que[r]] = false;//!!!
--r;//!!!
}
}

void rebuild()
{
cnt = 0;
for (int i = 1;i <= n;i++)
{
int c = head[i];
while(c)
{
if (belong[i] != belong[e[c].node])
{
d[++cnt].node = belong[e[c].node];
d[cnt].next = h[belong[i]];
h[belong[i]] = cnt;
}
c = e[c].next;
}
}
}

void tarjan()
{

for (int i = 1;i <= n;i++)
if (!vis[i]) dfs(i);
rebuild();
}

void work()
{
for (int i = 1;i <= scc;i++)
if (!h[i])
{
if (ans)
{
ans = 0;
return;
}
else ans = hav[i];
}
}

int main()
{
init();
tarjan();
work();
printf("%d\n",ans);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: