poj 2186 Popular Cows 强连通分量
2016-06-04 10:27
405 查看
题目大意
n头奶牛,给出若干个欢迎关系a b,表示a欢迎b,欢迎关系是单向的,但是是可以传递的。另外每个奶牛都是欢迎他自己的。求出被所有的奶牛欢迎的奶牛的数目
分析
先跑一遍taijian算法。那么出度为0的强连通分量代表的就是受其他奶牛欢迎的,但是如果出度为0的强连通分量的个数大于1那么则无解。因为将至少有两个分量里的奶牛互相不喜欢(因为他们的出度为0,不连接其他点,就不喜欢另一个同样情况的强连通分量)。所以我们的算法就是如果出度为0的强连通分量的个数是1.那么我们算出这里面点的个数就是最后的答案。
代码
const
maxe=500000;
maxv=20000;
type
rec=record
x,y,w,next:longint;
end;
var
n,m:longint;
g:array[1..maxe] of rec;
ls:array[1..maxv] of longint;
v,a,ru,cu:array[1..maxv] of longint;
low,dfn:array[1..maxv] of longint;
zan:array[1..maxv] of longint;
tot,ans,tot1:longint;
i,j,k:longint;
procedure dfs(r:longint);
var
i,j,k:longint;
begin
tot:=tot+1;
zan[tot]:=r;
v[r]:=1;
tot1:=tot1+1;
low[r]:=tot1;
dfn[r]:=tot1;
i:=ls[r];
while i<>0 do
with g[i] do
begin
if dfn[y]=0
then
begin
dfs(y);
if low[r]>low[y] then low[r]:=low[y];
end
else
if (low[r]>dfn[y]) and (v[y]=1)
then low[r]:=dfn[y];
i:=next;
end;
if low[r]=dfn[r]
then
begin
ans:=ans+1;
repeat
j:=zan[tot];
tot:=tot-1;
a[j]:=ans;
v[j]:=0;
until j=r;
end;
end;
begin
readln(n,m);
k:=0;
ans:=0;
for i:=1 to m do
begin
readln(j,k);
with g[i] do
begin
x:=j;
y:=k;
next:=ls[x];
ls[x]:=i;
end;
end;
for i:=1 to n do
if a[i]=0
then
dfs(i);
for i:=1 to n do
begin
j:=ls[i];
while j<>0 do
with g[j] do
begin
if a[x]<>a[y]
then
begin
cu[a[x]]:=cu[a[x]]+1;
ru[a[y]]:=ru[a[y]]+1;
end;
j:=next;
end;
end;
k:=0;
for i:=1 to ans do
if cu[i]=0 then k:=k+1;
if k<>1
then
begin
write(0);
halt;
end;
k:=0;
for i:=1 to ans do
if cu[i]=0 then k:=i;
j:=0;
for i:=1 to n do
if a[i]=k then j:=j+1;
write(j);
end.
n头奶牛,给出若干个欢迎关系a b,表示a欢迎b,欢迎关系是单向的,但是是可以传递的。另外每个奶牛都是欢迎他自己的。求出被所有的奶牛欢迎的奶牛的数目
分析
先跑一遍taijian算法。那么出度为0的强连通分量代表的就是受其他奶牛欢迎的,但是如果出度为0的强连通分量的个数大于1那么则无解。因为将至少有两个分量里的奶牛互相不喜欢(因为他们的出度为0,不连接其他点,就不喜欢另一个同样情况的强连通分量)。所以我们的算法就是如果出度为0的强连通分量的个数是1.那么我们算出这里面点的个数就是最后的答案。
代码
const
maxe=500000;
maxv=20000;
type
rec=record
x,y,w,next:longint;
end;
var
n,m:longint;
g:array[1..maxe] of rec;
ls:array[1..maxv] of longint;
v,a,ru,cu:array[1..maxv] of longint;
low,dfn:array[1..maxv] of longint;
zan:array[1..maxv] of longint;
tot,ans,tot1:longint;
i,j,k:longint;
procedure dfs(r:longint);
var
i,j,k:longint;
begin
tot:=tot+1;
zan[tot]:=r;
v[r]:=1;
tot1:=tot1+1;
low[r]:=tot1;
dfn[r]:=tot1;
i:=ls[r];
while i<>0 do
with g[i] do
begin
if dfn[y]=0
then
begin
dfs(y);
if low[r]>low[y] then low[r]:=low[y];
end
else
if (low[r]>dfn[y]) and (v[y]=1)
then low[r]:=dfn[y];
i:=next;
end;
if low[r]=dfn[r]
then
begin
ans:=ans+1;
repeat
j:=zan[tot];
tot:=tot-1;
a[j]:=ans;
v[j]:=0;
until j=r;
end;
end;
begin
readln(n,m);
k:=0;
ans:=0;
for i:=1 to m do
begin
readln(j,k);
with g[i] do
begin
x:=j;
y:=k;
next:=ls[x];
ls[x]:=i;
end;
end;
for i:=1 to n do
if a[i]=0
then
dfs(i);
for i:=1 to n do
begin
j:=ls[i];
while j<>0 do
with g[j] do
begin
if a[x]<>a[y]
then
begin
cu[a[x]]:=cu[a[x]]+1;
ru[a[y]]:=ru[a[y]]+1;
end;
j:=next;
end;
end;
k:=0;
for i:=1 to ans do
if cu[i]=0 then k:=k+1;
if k<>1
then
begin
write(0);
halt;
end;
k:=0;
for i:=1 to ans do
if cu[i]=0 then k:=i;
j:=0;
for i:=1 to n do
if a[i]=k then j:=j+1;
write(j);
end.
相关文章推荐
- shell if 判断
- win 与linux 下载
- linux内核中的软中断的实现
- Linux学习之变量测试与内容替换
- Grabcut算法----opencv2.4.11
- Linux下rc.local不执行问题
- OpenCV 配置
- Linux find exec 记录
- linux命令笔记(随时更新)
- CentOS7安装fcitx中文输入法
- Expectation Maximization Algorithm---opencv2.4.11
- tomcat(20)基于JMX的管理
- hadoop、spark学习中常用的linux命令
- OpenCV中关于求算图像的直方图(二)
- 【黑马Android】(13)Linux操作系统/cron计划任务
- Linux awk 命令
- 利用Docker Registry服务实现多数据中心的部署优化
- TOMCAT JAVA_HOME or JRE_HOME environment variable is not defined correctly
- 随机数发生器&绘制文字---opencv2.4.11
- 2.copy构造函数和拷贝操作符‘=’的区别