博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2186 Popular Cows
阅读量:4620 次
发布时间:2019-06-09

本文共 1927 字,大约阅读时间需要 6 分钟。

 

大意:牛牛之间互相喜欢,而且这种喜欢具有传递性,要求你求出最受欢迎的牛牛们的个数(A single integer that is the number of cows who are considered popular by every other cow. 

思路:通过“缩点”之后,然后求强连通分量出度的个数,如果为一,那么求出这个“缩点”里所有牛牛的个数。如果大于一,没有符合条件的,手推一遍即可证实。

CODE:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using 
namespace std;
#define MAXN 10010
#define MAXM 100010 
struct Edge
{
    
int v, w, next;
}edge[MAXM];
int first[MAXN], stack[MAXN], ins[MAXN], dfn[MAXN], low[MAXN];
int belong[MAXM];
int outd[MAXN];
int n, m;
int cnt;
int scnt, top, tot;
void init()
{
    cnt = 
0;
    scnt = top = tot = 
0;
    memset(first, -
1
sizeof(first));
    memset(dfn, 
0
sizeof(dfn));
}
void read_graph(
int u, 
int v)
{
    edge[cnt].v = v;
    edge[cnt].next = first[u];
    first[u] = cnt++;
}
void dfs(
int u)
{
    
int t;
    low[u] = dfn[u] = ++tot;
    ins[u] = 
1;
    stack[top++] = u;
    
for(
int e = first[u]; e != -
1; e = edge[e].next)
    {
        
int v = edge[e].v;
        
if(!dfn[v])
        {
            dfs(v);
            low[u] = min(low[u], low[v]);
        }
        
else 
if(ins[v])
        {
            low[u] = min(low[u], dfn[v]);
        }
    }
    
if(low[u] == dfn[u])
    {
        ++scnt;
        
do
        {
            t = stack[--top];
            belong[t] = scnt;
            ins[t] = 
0;
        }
while(t != u);
    }
}
void Tarjan()
{
    
for(
int v = 
1; v <= n; v++) 
if(!dfn[v])
        dfs(v);
}
void solve()
{
    Tarjan(); 
//
Tarjan();
    memset(outd, 
0
sizeof(outd));
    
for(
int u = 
1; u <= n; u++)
    {
        
for(
int e = first[u]; e != -
1; e = edge[e].next)
        {
            
int v = edge[e].v;
            
if(belong[u] != belong[v])    outd[belong[u]]++; 
//
强连通分量的出度增加,即缩点的出度增加。
        }
    }
    
int index = 
0, flag = 
0;
    
for(
int i = 
1; i <= scnt; i++) 
if(!outd[i]) 
//
如果强连通的出度为0
    {
        index++;
        flag = i; 
//
标记所在强连通
    }
    
if(index > 
1) printf(
"
0\n
"); 
//
出度为0的强连通不只一个 
    
else
    {
        index = 
0;
        
for(
int i = 
1; i <= n; i++) 
if(belong[i] == flag) index++; 
//
所有的顶点属于出度为0的强连通分量点的数目 
        printf(
"
%d\n
", index);
    }
}
int main()
{
    
while(~scanf(
"
%d%d
", &n, &m))
    {
        init();
        
while(m--)
        {
            
int u, v;
            scanf(
"
%d%d
", &u, &v);
            read_graph(u, v);
        }
        solve();
    }
    
return 
0;
}

 

 

转载于:https://www.cnblogs.com/g0feng/archive/2012/10/29/2745389.html

你可能感兴趣的文章
BeanDefinition的Resource定位——2
查看>>
学习记事
查看>>
java 子类重写父类的方法应注意的问题
查看>>
[LevelDB] LevelDB理论基础
查看>>
如果部署Excel 加载项?
查看>>
【codecombat】 试玩全攻略 第一关kithguard地牢
查看>>
【DP】 POJ 1191 棋盘分割 记忆化搜索
查看>>
自动化测试 Appium之Python运行环境搭建 Part2
查看>>
说说DBA职责和目标
查看>>
从头认识Spring-2.4 基于java的标准注解装配-@Inject-限定器@Named
查看>>
sql server 实现多表连接查询
查看>>
Python标准库:内置函数getattr(object, name[, default])
查看>>
转:android 自定义RadioButton样式
查看>>
HTTP请求过程
查看>>
织梦多域名解析到同一个空间导致打开链接不一致怎么办?
查看>>
Xcode10 library not found for -lstdc++ 找不到问题
查看>>
Mysql 8.0.13如何重置密码
查看>>
发布功能完成
查看>>
excel 合并单元格
查看>>
iOS设计模式简介
查看>>