poj 2186 (强连通缩点)
题意:有N只奶牛,奶牛有自己认为最受欢迎的奶牛。奶牛们的这种“认为”是单向可传递的,当A认为B最受欢迎(B不一定认为A最受欢迎),且B认为C最受欢迎时,A一定也认为C最受欢迎。现在给出M对这样的“认为...”的关系,问有多少只奶牛被除其本身以外的所有奶牛关注。
思路:既然有单向传递关系,那么关系图可能就形成了环,一个环内的奶牛互相认为。如果把这些环用一个点代替的话,建反图,就成了一个有向无环图了,直接遍历求出入度为0的点有多少个子节点就可以了。
#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;
const int N=10010;
int low[N],dfs[N],ans,idx,cont[N],head[N],num,indep[N],belong[N],sum;
bool ins[N];
stack<int>Q;
struct edge
{
int st,ed,next;
}e[N*10];
void addedge(int x,int y)
{
e[num].st=x;e[num].ed=y;e[num].next=head[x];head[x]=num++;
}
void Tarjan(int u)//缩点
{
int i,v;
Q.push(u);
ins[u]=1;
low[u]=dfs[u]=idx++;
for(i=head[u];i!=-1;i=e[i].next)
{
v=e[i].ed;
if(dfs[v]==-1)
{
Tarjan(v);
low[u]=low[u]>low[v]?low[v]:low[u];
}
else if(ins[v]==1)
low[u]=low[u]>dfs[v]?dfs[v]:low[u];
}
if(dfs[u]==low[u])
{
do
{
v=Q.top();
Q.pop();
ins[v]=0;
belong[v]=ans;
cont[ans]++;
}while(v!=u);
ans++;
}
}
int Dfs(int u)
{
int i,v,temp=0;
for(i=head[u];i!=-1;i=e[i].next)
{
v=e[i].ed;
temp+=Dfs(v);
}
return temp+cont[u];//子节点+自己环内的所有点
}
int main()
{
int i,n,m,x,y;
while(scanf("%d%d",&n,&m)!=-1)
{
memset(head,-1,sizeof(head));
num=0;ans=idx=0;
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
addedge(x,y);
}
memset(cont,0,sizeof(cont));
memset(ins,0,sizeof(ins));
memset(dfs,-1,sizeof(dfs));
for(i=1;i<=n;i++)
{
if(dfs[i]==-1)
Tarjan(i);
}
memset(head,-1,sizeof(head));
memset(indep,0,sizeof(indep));
num=0;
for(i=0;i<m;i++)
{
x=belong[e[i].st];
y=belong[e[i].ed];
if(x==y)continue;
addedge(y,x);//建反图
indep[x]++;
}
sum=0;
for(i=0;i<ans;i++)
{
if(indep[i]==0)
if(Dfs(i)==n)
sum+=cont[i];
}
printf("%d\n",sum);
}
return 0;
}
poj 2186 (强连通缩点)的更多相关文章
- poj 2186 强连通+缩点
题意:有一群牛,求被所有牛都认可的牛的个数 每个连通分量建一个缩点,出度为零的缩点包含的点的个数即为要求值 如果有多个出度为零的,直接输出零,否则输出那唯一一个出度为零的缩点包含的点的个数 #incl ...
- poj 2186 强连通分量
poj 2186 强连通分量 传送门 Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 33414 Acc ...
- poj 2553强连通+缩点
/*先吐槽下,刚开始没看懂题,以为只能是一个连通图0T0 题意:给你一个有向图,求G图中从v可达的所有点w,也都可以达到v,这样的v称为sink.求这样的v. 解;求强连通+缩点.求所有出度为0的点即 ...
- poj 3114(强连通缩点+SPFA)
题目链接:http://poj.org/problem?id=3114 思路:题目要求很简单,就是求两点之间的花费的最短时间,不过有一个要求:如果这两个city属于同一个国家,则花费时间为0.如何判断 ...
- poj 2186 强连通入门题目
每头牛的梦想就是成为牛群中最受欢迎的牛. 在一群N(1 <= N <= 10,000)母牛中, 你可以得到M(1 <= M <= 50,000)有序的形式对(A,B),告诉你母 ...
- poj 2762 强连通缩点+拓扑排序
这题搞了好久,先是拓扑排序这里没想到,一开始自己傻乎乎的跑去找每层出度为1的点,然后才想到能用拓扑排序来弄. 拓扑排序的时候也弄了挺久的,拓扑排序用的也不多. 题意:给一个图求是否从对于任意两个点能从 ...
- Network of Schools POJ - 1236(强连通+缩点)
题目大意 有N个学校,这些学校之间用一些单向边连接,若学校A连接到学校B(B不一定连接到A),那么给学校A发一套软件,则学校B也可以获得.现给出学校之间的连接关系,求出至少给几个学校分发软件,才能使得 ...
- POJ(2186)强连通分量分解
#include<cstdio> #include<vector> #include<cstring> using namespace std; ; vector& ...
- POJ 2186 tarjan+缩点 基础题
Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 37111 Accepted: 15124 De ...
随机推荐
- LeeCode-Rotate Array
Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array ...
- Windows多线程同步系列之一-----互斥对象
多线程同步之互斥对象 作者:vpoet mail:vpoet_sir@163.com 对卖票问题进行线程间同步,本文将在上文的基础上,使用互斥对象对线程进行同步. 首先看看windows API ...
- 【斗地主技巧】斗地主算法逻辑中的天之道<转>
******************************************************************** 作者比较喜欢玩斗地主,所以经常搜集一些网友斗地主的心得,下面这 ...
- IOS 计算密码强度
+ (BOOL) judgeRange:(NSArray*)conditionArr Password:(NSString*)password { NSRange range; BOOL result ...
- Kali下使用libheap
Kali下使用libheap 在github上,可以libheap用来帮助调试堆溢出.链接见:https://github.com/cloudburst/libheap 但是最后一次更新在一年前了,我 ...
- mapkit定位以及俯视视图
1.导入框架MapKit.framework,CoreGraphics.framework
- jquery mobile 入门级实战1
第一步:使用CDN接入jquery mobile CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环 ...
- [Effective Modern C++] Item 6. Use the explicitly typed initializer idiom when auto deduces undesired types - 当推断意外类型时使用显式的类型初始化语句
条款6 当推断意外类型时使用显式的类型初始化语句 基础知识 当使用std::vector<bool>的时候,类型推断会出现问题: std::vector<bool> featu ...
- onbeforepaste
onbeforepaste事件用法 onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').rep ...
- synchronized 方式实现监控器中数据成员的同步
要对监控器中的数据成员进行访问,在考虑到多线程的情况下必须使用同步代码块来改变监控器中数据成员的值: synchronized (mAdapterLocking) { if (pEvery == 0) ...