poj 2186 Popular Cows

原创 2012年03月21日 16:20:35
类型:有向图连通性

题目:有n头牛,m个形式如(A, B)表示牛B受牛A欢迎,求受所有牛欢迎的牛的数量

来源:USACO 2003 Fall

思路:在同一强连通分量中,不同牛之间相互受欢迎,可以将其看做一个点[缩点],构造新图。假设新图连通,如果某个牛受所有其他牛欢迎,则其顶点的出度为0,其他点出度不为0,否则将不存在牛受其他所有牛欢迎。如果新图不连通,则存在多个出度为0的点。所以可以通过判断新图点出度为0的个数是否为1来判断解是否存在,如果存在,输出该强连通分量中的点

// poj 2186 Popular Cows
// ac 676K 79MS
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define MIN(a,b) (a) < (b) ? (a) : (b)
#define clr(a,b) memset(a,b,sizeof(a))
#define FOR(i,a,b) for((i) = (a); (i) < (b); ++i)
#define FORE(i,a,b) for((i) = (a); (i) <= (b); ++i)
#define MAXN 10100
#define MAXM 50100

bool vis[MAXN];
int num, cnt, count_node, kk, m, n, cnt_num;
int top, u[MAXM], v[MAXM], step[MAXN], low[MAXN];
int head[MAXN],belong[MAXN],stack[MAXN];
struct edge{
    int v,nxt;
}e[MAXM];

void Tarjan(int u) {
	int i, j, v;

	step[u] = low[u] = ++num;
	stack[++top] = u, vis[u] = true;//in_stack[u] = true;
	for(i = head[u]; i != -1; i = e[i].nxt) {
		v = e[i].v;
		if(!step[v]) {
			Tarjan(v);
			low[u] = MIN(low[u],low[v]);
		}
		else if(vis[v])
			low[u] = MIN(low[u],step[v]);
	}
	if(step[u] == low[u]){
		cnt_num++;
		do{
			j = stack[top--];
			vis[j] = false;
//			in_stack[j] = false;
			belong[j] = cnt_num;
		}while(j != u);
	}
}

int main() {
	int i,j,u, v;

	while(scanf("%d %d", &n, &m) != EOF){
		clr(head, -1);
		clr(step, 0);
		clr(belong, 0);
		clr(vis, false); //clr(in_stack,false);
		top = num = cnt = cnt_num = kk = count_node = 0;
		FOR(i, 0, m) {
			scanf("%d %d", &u, &v);
			e[cnt].v = v;
			e[cnt].nxt = head[u];
			head[u] = cnt++;
		}
		FORE(i, 1, n)
			if(!step[i])
                Tarjan(i);
		FORE(i, 1, n)
			for(j = head[i]; j != -1; j = e[j].nxt)
				if(belong[i] != belong[e[j].v])
					vis[belong[i]] = true;
		FORE(i, 1, cnt_num)
			if(!vis[i]) {
                count_node++;
                kk = i;
            }
		//!!!
		if(count_node != 1)
			printf("0\n");
		else{
			int ans = 0;
			FORE(j, 1, n)
				if(belong[j] == kk) ans++;
			printf("%d\n",ans);
		}
	}
    return 0;
}


POJ2186-Popular Cows

转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6764104   大致题意: 有N只奶牛,其中奶牛A认为奶牛B备受...
  • lyy289065406
  • lyy289065406
  • 2011年09月09日 16:06
  • 5015

poj 2186 Popular Cows

Popular Cows Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) To...
  • foreverwy
  • foreverwy
  • 2015年11月02日 20:00
  • 109

POJ 2186 —— Popular Cows

原题:http://poj.org/problem?id=2186 题意:问有多少个点满足条件 —— 其他所有的点都可以到达它; 思路:先求强连通分量,然后反向构建DAG图,新图中的点权就...
  • L_avender
  • L_avender
  • 2016年04月15日 22:51
  • 117

POJ 2186: Popular Cows

题目链接:http://poj.org/problem?id=2186 题意: 有一群绵羊, 现在有一些喜欢关系,喜欢关系是可以传递的。 问有多少绵羊直接或间接地被所有绵羊喜欢。 算法: 首先...
  • frog1902
  • frog1902
  • 2013年07月27日 23:13
  • 824

POJ 2186 Popular Cows

抽象成:在一个有向图中,找所有的点都可以到达的点的个数 根据题意结果必在一个强连通分量里(所有的答案之间肯定互相能到达)。用tarjan找出所有的连通分量,如果某个连通分量里有连到外面的边,则这个分...
  • u012797220
  • u012797220
  • 2014年01月22日 22:34
  • 966

POJ 2186 Popular Cows

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 32017   Ac...
  • qq_35776409
  • qq_35776409
  • 2017年03月17日 16:17
  • 44

poj 2186——Popular Cows

tarjan缩点 题意:有n个牛,m个关系。并且如果a->b  b->c  则a->c. 先用tarjan把各个强连通分量缩成一个点,(这个点里的奶牛互相仰慕)并且记录下各个强连通分量里点的个数。 找...
  • softrice2012
  • softrice2012
  • 2013年07月26日 16:32
  • 661

poj 2186 Popular Cows

n(1 问你,能够得到所有牛推举的牛有多少头? 题解:强连通分支+缩点 强连通分支为最大的连通子图,在这个子图中任意两点都是可达的。 在一个强连通分支里面,根据推举...
  • ljd4305
  • ljd4305
  • 2013年10月02日 15:48
  • 533

Poj 2186 Popular Cows

Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 29240 Accepted...
  • sinat_34550050
  • sinat_34550050
  • 2016年05月15日 14:30
  • 415

POJ 2186(Popular Cows)

题意:有n个奶牛,它们之间互相膜拜,并且如果A膜拜B,B膜拜C则,A也膜拜C,求有多少头奶牛被所有奶牛都膜拜; 思路:强连通分量+缩点,刚学SCC,这题是书上的例题,顺手敲下熟悉下,用的是Kosara...
  • joy_go
  • joy_go
  • 2013年04月17日 12:31
  • 399
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 2186 Popular Cows
举报原因:
原因补充:

(最多只允许输入30个字)