poj 2186 强连通分量
poj 2186 强连通分量
Popular Cows
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 33414 Accepted: 13612
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.
我们可以将一个强联通分量看成一个点进行处理,因为这个强连通分量中的点都是相互可达的,那么只要其中一头牛成为红人,那么其他牛也是一样的,同时我们可以得到两个结论
- 最终答案必然只是一个强连通分量(如果有两个,那么根据所有点必须可达这个点的条件,那么这两个点集必然属于一个强连通分量,与假设不合,证明成立)
- 最终答案就是拓扑排序最后的那个强连通分量,这是根据拓扑排序的性质得来的
所以我们只需要求出那个强连通分量,最终再反向dfs验证是否可达每个点,这题就解出来了。
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#define ll long long
#define inf 1000000000LL
#define mod 1000000007
using namespace std;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int N=1e4+10;
const int M=5e4+10;
int A[M],B[M],n,m;
vector<int> G[N]; //图
vector<int>rG[N]; //反向图
vector<int>vs; //后序遍历的顶点列表
bool vis[N];
int cmp[N]; //所属强连通分量的拓扑序
int sum[N];
void Addedge(int from,int to){
G[from].push_back(to);
rG[to].push_back(from);
}
void dfs(int v){
vis[v]=true;
for(int i=0;i<G[v].size();i++){
if(!vis[G[v][i]]) dfs(G[v][i]);
}
vs.push_back(v);
}
void rdfs(int v,int k){
vis[v]=true;
cmp[v]=k;
sum[k]++;
for(int i=0;i<rG[v].size();i++){
if(!vis[rG[v][i]]) rdfs(rG[v][i],k);
}
}
int scc(){
memset(vis,0,sizeof(vis));
vs.clear();
for(int v=0;v<n;v++){
if(!vis[v]) dfs(v);
}
memset(vis,0,sizeof(vis));
int k=0;
for(int i=vs.size()-1;i>=0;i--){
if(!vis[vs[i]]) rdfs(vs[i],k++); //遍历每个联通分量的点集
}
return k;
}
int main(){
// while(true)
{
n=read();m=read();
for(int i=0; i<m; i++){
A[i]=read();B[i]=read();
Addedge(A[i]-1,B[i]-1);
}
int count=scc();
int u=0,num=sum[count-1];
for(int v=0;v<n;v++){
if(cmp[v]==count-1){
u=v;
break;
}
}
memset(vis,0,sizeof(vis));
rdfs(u,0);
for(int v=0;v<n;v++){
if(!vis[v]){
num=0;
break;
}
}
printf("%d\n",num);
}
return 0;
}
/*
5 5
1 2
1 3
2 4
4 5
5 2
*/
poj 2186 强连通分量的更多相关文章
- POJ(2186)强连通分量分解
#include<cstdio> #include<vector> #include<cstring> using namespace std; ; vector& ...
- Popular Cows POJ - 2186(强连通分量)
Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10, ...
- poj 1904(强连通分量+输入输出外挂)
题目链接:http://poj.org/problem?id=1904 题意:有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国 ...
- poj 2762(强连通分量+拓扑排序)
题目链接:http://poj.org/problem?id=2762 题意:给出一个有向图,判断任意的两个顶点(u,v)能否从u到达v,或v到达u,即单连通,输出Yes或No. 分析:对于同一个强连 ...
- poj 1904 强连通分量
思路:先有每个儿子向所有他喜欢的姑娘建边,对于最后给出的正确匹配,我们建由姑娘到相应王子的边.和某个王子在同一强连通分量,且王子喜欢的姑娘都是该王子能娶得.思想类似匈牙利算法求匹配的时候,总能找到增广 ...
- poj 1904(强连通分量+完美匹配)
传送门:Problem 1904 https://www.cnblogs.com/violet-acmer/p/9739990.html 参考资料: [1]:http://www.cnblogs.co ...
- poj 1236(强连通分量分解模板题)
传送门 题意: N(2<N<100)个学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输. 问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都 ...
- poj 2186 强连通入门题目
每头牛的梦想就是成为牛群中最受欢迎的牛. 在一群N(1 <= N <= 10,000)母牛中, 你可以得到M(1 <= M <= 50,000)有序的形式对(A,B),告诉你母 ...
- poj 2186 (强连通缩点)
题意:有N只奶牛,奶牛有自己认为最受欢迎的奶牛.奶牛们的这种“认为”是单向可传递的,当A认为B最受欢迎(B不一定认为A最受欢迎),且B认为C最受欢迎时,A一定也认为C最受欢迎.现在给出M对这样的“认为 ...
随机推荐
- 二进制流BinaryFormatter存储读取数据的细节测试
二进制流的使用很方便,为了更好的理解应用它,我创建简单对象开始测试它的增加特性和减少特性. [Serializable] class Data----------开始时候的存储对象 { public ...
- Java实现求二叉树的路径和
题: 解: 这道题考的是如何找出一个二叉树里所有的序列. 我的思路是先从根节点开始遍历,找出所有的子节点,因为每个子节点只有一个父节点,再根据每个子节点向上遍历找出所有的序列,再判断序列的总和. 这样 ...
- Spark学习之Spark Streaming(9)
Spark学习之Spark Streaming(9) 1. Spark Streaming允许用户使用一套和批处理非常接近的API来编写流式计算应用,这就可以大量重用批处理应用的技术甚至代码. 2. ...
- vim设置默认显示行号
vim /root/.vimrc 设置在当前登录用户根目录下,.vimrc文件本身不存在,创建后之间添加下面配置保存即可 set number
- 在sql server 如何创建一个只读账户
设置步骤 进入Sqlserver Management Studio(MSSQL客户端) 选择安全性->登录名->右键新建登录名 在常规里输入用户名和密码 在"用户映射" ...
- 通过SSDT HOOK实现进程保护和进程隐藏
---恢复内容开始--- 首先,我要说一件很重要的事,本人文采不好,如果哪里说的尴尬了,那你就尴尬着听吧...... SSDT HOOK最初貌似源于Rookit,但是Rookit之前有没有其他病毒使用 ...
- [转载]迅为4418开发板Qt移植移动4G模块第一部分
本文转自迅为论坛:http://topeetboard.com 平台:iTOP-4418开发板 1.首先要配置内核,这个一步和Android系统移植3G或者4G模块是一样的.一般模块的 ...
- leetcode_650. 2 Keys Keyboard_dp
https://leetcode.com/problems/2-keys-keyboard/ 初始一个A,两种操作,复制当前所有A,粘贴,问得到n个A最少需要多少步操作. class Solution ...
- hibernate 离线查询(DetachedCriteria)
离线查询使用DetachedCriteria对象设置限制条件,然后再通过session获取Criteria对象. 使用场景: 例如Biz类和Dao类,在Dao类中利用session操作CRUD,如果你 ...
- TabWight
//修改站号void CDlgParamView::OnPushButton_2_Tab8Clicked(){ // int iSel = m_listStation.GetSelectionMark ...