POJ 2186 Popular Cows
2014-11-27 13:10
218 查看
【题意】给定牛群有n头,有m条关系表示x认为y受欢迎,若x认为y受欢迎,y认为z受欢迎,则x认为z受欢迎,问几头牛被其他所有牛欢迎?
【分析】分类讨论欢迎的情况:(1)组成环 (2)不成环
对于(1),又由“若x认为y受欢迎,y认为z受欢迎,则x认为z受欢迎”,易想到用强联通分量化成无向DAG
对于(2),再搜一遍,根据定理,若出边为0则输出
注:tarjan算法79ms,Kosaraju算法119ms,tarjan还是快一些的
【代码】
(1)KOSARAJU算法#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int N=10070;
const int M=64020;
struct G
{
int v,next;
};
G map[M];
int n,m,dfn
,low
,tot,d
,hd
,s
,c
,v
,color;
void ins(int u,int v)
{
map[++tot].v=v;
map[tot].next=hd[u];
hd[u]=tot;
}
void init(void)
{
scanf("%d%d",&n,&m);
while (m--)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);
}
}
int min(int i,int j)
{
return i<j?i:j;
}
void tarjan(int u)
{
dfn[u]=low[u]=++tot;
s[++s[0]]=u;
int t=hd[u];
while (t)
{
if (!dfn[map[t].v])
{
tarjan(map[t].v);
low[u]=min(low[u],low[map[t].v]);
}
else if (!c[map[t].v]) low[u]=min(low[u],dfn[map[t].v]);
t=map[t].next;
}
if (low[u]==dfn[u])
{
color++;
while (s[0]&&s[s[0]]^u) c[s[s[0]--]]=color;
if (s[0]) c[s[s[0]--]]=color;
}
}
void GCC(int u)
{
v[u]++;
int t=hd[u];
while (t)
{
if (!v[map[t].v]) GCC(map[t].v);
d[c[u]]+=c[u]!=c[map[t].v];
t=map[t].next;
}
}
void work(void)
{
tot=0;
for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
for (int i=1;i<=n;i++) if (!v[i]) GCC(i);
int t=-1,cnt=0;
for (int i=1;i<=color;i++) if (!d[i]) t=(t==-1?i:0);
for (int i=1;i<=n;i++) cnt+=t==c[i];
printf("%d\n",cnt);
}
int main(void)
{
init();
work();
return 0;
}
(2)tarjan算法
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int N=10070;
const int M=64020;
struct G
{
int v,next;
};
G map[M];
int n,m,dfn
,low
,tot,d
,hd
,s
,c
,v
,color;
void ins(int u,int v)
{
map[++tot].v=v;
map[tot].next=hd[u];
hd[u]=tot;
}
void init(void)
{
scanf("%d%d",&n,&m);
while (m--)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);
}
}
int min(int i,int j)
{
return i<j?i:j;
}
void tarjan(int u)
{
dfn[u]=low[u]=++tot;
s[++s[0]]=u;
int t=hd[u];
while (t)
{
if (!dfn[map[t].v])
{
tarjan(map[t].v);
low[u]=min(low[u],low[map[t].v]);
}
else if (!c[map[t].v]) low[u]=min(low[u],dfn[map[t].v]);
t=map[t].next;
}
if (low[u]==dfn[u])
{
color++;
while (s[0]&&s[s[0]]^u) c[s[s[0]--]]=color;
if (s[0]) c[s[s[0]--]]=color;
}
}
void GCC(int u)
{
v[u]++;
int t=hd[u];
while (t)
{
if (!v[map[t].v]) GCC(map[t].v);
d[c[u]]+=c[u]!=c[map[t].v];
t=map[t].next;
}
}
void work(void)
{
tot=0;
for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
for (int i=1;i<=n;i++) if (!v[i]) GCC(i);
int t=-1,cnt=0;
for (int i=1;i<=color;i++) if (!d[i]) t=(t==-1?i:0);
for (int i=1;i<=n;i++) cnt+=t==c[i];
printf("%d\n",cnt);
}
int main(void)
{
init();
work();
return 0;
}
【小结】一种转化思想,有向图转化为无向图,从而多了某些性质
相关文章推荐
- poj-2186-Popular Cows-缩点
- poj 2186 Popular Cows
- poj 2186 Popular Cows
- poj 2186【Popular Cows】1236【Network of Schools】2553【The Bottom of a Graph】
- poj 2186 Popular Cows 强连通
- 【POJ】2186 - Popular Cowsa 强连通分量【模版】
- POJ 2186 Popular Cows 强连通分量 kosaraju
- POJ 2186 Popular Cows
- poj 2186 Popular Cows
- POJ 2186-Popular Cows
- POJ 2186 Popular Cows
- poj 2186 Popular Cows(第一道强连通分支题)
- POJ2186--Popular Cows
- POJ 2186 Popular Cows
- poj 2186 Popular Cows (Tarjan 强连通分量+压缩点)
- 强连通分量分解 Kosaraju算法 (poj 2186 Popular Cows)
- POJ 2186 Popular Cows
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows【强连通Kosaraju+缩点】
- POJ 2186 Popular Cows