poj Popular Cows(tarjan +缩点)


Language:
Default

Popular Cows

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 24384   Accepted: 10007

Description

Every cow‘s dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive,
if A thinks B is popular and B thinks C is popular, then A will also think that C is

popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.

Input

* Line 1: Two space-separated integers, N and M

* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.

Output

* Line 1: A single integer that is the number of cows who are considered popular by every other cow.

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

Hint

Cow 3 is the only cow of high popularity.

Source

USACO 2003 Fall

题意: n头牛相互羡慕,可以传递羡慕,问被所有牛羡慕的牛的最大数目

思路:

tarjan缩点,把不同的点规划到一个强联通分支,最后判断强连通分支出度为0的点是否唯一,唯一则有解,答案是该强连通分支的点的数目,否者无解

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>

#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define eps 1e-8
typedef __int64 ll;

#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define bug         pf("Hi\n")

using namespace std;

#define N 10024

int head[N],low[N],time[N],e_num,tim_num;
int n,m,ans,instack[N],vis[N],type[N],out[N];

struct stud{
  int to,next;
}e[N*10];

stack<int>q;

inline void add(int u,int v)
{
    e[e_num].to=v;
    e[e_num].next=head[u];
    head[u]=e_num++;
}

void tarjan(int x)
{
    int i,j;
    q.push(x);
    instack[x]=1;

    time[x]=low[x]=++tim_num;

    for(i=head[x];i!=-1;i=e[i].next)
    {
        int to=e[i].to;
        if(time[to]==0)
        {
            tarjan(to);
            if(low[x]>low[to]) low[x]=low[to];
        }
        else
            if(instack[to]&&low[x]>time[to])
                low[x]=time[to];
    }

    if(low[x]==time[x])
    {
        ans++;
        do{
            j=q.top();
            q.pop();
            instack[j]=0;
            type[j]=ans;   //标记j 属于第几个联通分支
            vis[ans]++;    //这个联通分支的点+1
           // printf("%d ans=%d\n",j,ans);
        }while(j!=x);
    }
}

void solve()
{
    int i,j;
    mem(time,0);
    mem(instack,0);
    mem(out,0);
    mem(vis,0);

    ans=tim_num=0;

    for(i=1;i<=n;i++)
        if(time[i]==0)
          tarjan(i);

	for(i=1;i<=n;i++)
		for(j=head[i];j!=-1;j=e[j].next)
	{
		int to=e[j].to;

		if(type[i]!=type[to])
			{
				out[type[i]]=1;  //标记有出度的联通分支
			}
	}

	int t=0,pos;

	for(i=1;i<=ans;i++)    //一共有ans个联通分支,取出其中
		if(out[i]==0)
	{
		t++;
		pos=i;
		if(t>1) break;
	}

   //如果出度为0的联通分支只有一个,那么这个联通分支的个数就是答案,
   //否则,无解
	if(t==1)
		printf("%d\n",vis[pos]);
	else
		printf("0\n");

}

int main()
{
    int i,j;
    scanf("%d%d",&n,&m);
    {
        int u,v;
        e_num=0;

        mem(head,-1);

        while(m--)
        {
            sff(u,v);
            add(u,v);
        }
        solve();
    }
    return 0;
}
时间: 2024-10-10 00:01:14

poj Popular Cows(tarjan +缩点)的相关文章

POJ 2186 Popular Cows -- tarjan 缩点

链接: POJ 2186 Popular Cows 题意: 每一头牛都希望在牛群里面备受瞩目,在一个牛群中有N头牛(1<=N<=10000),你被给予M(1<=M<=50000)个关系对,形式如(A,B),这意味着A牛认为B牛比它更受欢迎,由于这种欢迎度是满足传递性的,那么若是A牛认为B牛更受欢迎,B牛认为C牛更受欢迎,那么A牛也会认为C牛更受欢迎.你的任务是计算出被所有牛受欢迎的牛的个数. 输入: 第一行两个整数 N 和 M 第2 到 M + 1 行,两个分开的数 A,B,意味着

POJ2186 Popular Cows [tarjan 缩点]

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31241   Accepted: 12691 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M &

POJ 2186 Popular Cows tarjan缩点算法

题意:给出一个有向图代表牛和牛喜欢的关系,且喜欢关系具有传递性,求出能被所有牛喜欢的牛的总数(除了它自己以外的牛,或者它很自恋). 思路:这个的难处在于这是一个有环的图,对此我们可以使用tarjan算法求出强连通分量,把强连通分量压缩成一个点,构成一个新的图,这个图一定是没有环的,如果有环就跟强连通分量的矛盾了.压缩成无环图以后这个图里面的点是不具有方向的,我们通过遍历每个节点所能连到的点,如果两点的id值即所在的强连通分量区域不同时,我们就把这个节点的出度加1.最后去找那些出度等于0的点,如果

USACO 2003 Fall Orange Popular Cows /// tarjan缩点 oj22833

题目大意: n头牛,m个崇拜关系,并且崇拜具有传递性 如果a崇拜b,b崇拜c,则a崇拜c 求最后有几头牛被所有牛崇拜 强连通分量内任意两点都能互达 所以只要强联通分量内有一点是 那么其它点也都会是 按照崇拜关系 即a崇拜b就连一条a到b的边 tarjan求得所有强联通分量并染色 而把一个强联通分量缩成一个超级点后 整个图的崇拜关系就变成了一个 有向无环图 此时被所有牛崇拜的牛就是 一个出度为0的超级点 只要把所有边再走一遍就可以计算出度 同时计算每个超级点内有多少个点 即从a出发到b的边 若a

Poj 2186 Popular Cows (Tarjan)

题目链接: Poj 2186 Popular Cows 题目描述: 有n只牛,牛之间存在一些关系,比如a认为b很受欢迎,b认为c很受欢迎,这样呢,a也会认为c很受欢迎,问根据给出的关系,有多少头牛被其他所有的牛都认为是受欢迎的? 解题思路: 对于一个有向无环图来说,其中有且仅有一个点出度为零,那么这个特殊的点,可以由其他任何点到达.那么接下来我们直接对所给的图进行强连通分量划分,然后把每个强连通分量看做一个点,判定出度为零的点有几个,如果有一个就输出这个点对应的强连通分量含有的节点个数,否则为零

Poj 2186 Popular Cows(Tarjan 强连通缩点)

传送门:Poj 2186 题意:给你n头牛,m种关系,A牛认为B牛是popular的,B牛认为C牛是popular的,则A也认为C是popular的,问最终有几头被所有牛认为是popular的牛 题解:强连通缩点基础题(虽然我Tarjan和缩点都是对的,但是最终讨论判断的时候写垮了(写了3天....还不是你懒!!!!过年划水这么多天缩点后找出度为零的点个数.然后讨论是否有这样子的点,如果没有则全都是(整个都是强连通图),如果只有一个,那么那个强连通分量所含的牛的个数就是所求解,如果有多个那么都是

poj 2186 Popular Cows 强连通缩点

[题意]:给出一群牛中,一头牛认为另一头牛受欢迎的m对关系,关系式可以传递的,即若a认为b受欢迎,b认为c受欢迎,那么a也认为c受欢迎.求最多有多少头牛被所有的牛认为受欢迎. [思路]:把这些关系形成的强连通图缩成点,就形成了一有向无环图,这个图里的出度为0的点(有且只有一个)就是被所有牛认为受欢迎的点,说明若这个点原来是强连通图就要求出这个强连通图里的总点数, 1 #include<iostream> 2 #include<stdio.h> 3 #include<strin

poj2186Popular Cows tarjan缩点

//n个奶牛, //A B 表示A认为B出名,而且其有传递性 //如A认为B出名,B认为C出名,那么A认为C出名 //问有多少头奶牛所有的奶牛都认为其出名 //先对这个图缩点,记录每一个缩点的个数,然后找出度为0有且只有一个点 //如果是,那么那个点缩了几个点就是答案 #include<cstdio> #include<cstring> #include<iostream> #include<vector> using namespace std ; con

POJ 2186 -- Popular Cows【强连通分支 &amp;&amp; Tarjan缩点】

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27198   Accepted: 10963 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M &