bzoj 1051 (强连通) 受欢迎的牛
题目:这里
题意:
Description
Input
Output
一个数,即有多少头牛被所有的牛认为是受欢迎的。
Sample Input
1 2
2 1
2 3
Sample Output
HINT
我是看了强连通入门(讲的很清楚):http://www.2cto.com/kf/201606/517227.html
Kosaraju算法第一次dfs1将所有的点按拓扑排序逆序存进栈,第二次dfs2(此时是逆着方向回去搜)将整个图分成若干个强连通分量,。
对于这个题,可以观察出最后受到所有牛的欢迎的牛必定是在其中一个强连通分量里面的,所以看哪个强连通分量是其余所有变量都能达到的,也就等同于缩点后的
新图里面哪个的出度为0,如果出度为0的分量只有一个,那么该分量其中点的个数就是答案,如果出度为0的分量个数超过一个,那么没有答案,输出为0.
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
using namespace std; const int M = 1e5 + ;
vector<int>q;
int sccno[M],sum[M],du[M],scc_cnt; struct Edge{
int to,next,from,odr;
}edge[M*];
int head1[M],head2[M],cas;
bool vis[M]; void add(int u,int v)
{
edge[++cas].next=head1[u];
edge[cas].odr=head2[v];
edge[cas].to=v;edge[cas].from=u;
head1[u]=cas;head2[v]=cas;
} void dfs1(int u)
{
for (int i=head1[u] ; i ; i=edge[i].next){
int v=edge[i].to;
if (vis[v]) continue;
vis[v]=true;
dfs1(v);
q.push_back(v);
}
} void dfs2(int u)
{
sccno[u]=scc_cnt;
sum[scc_cnt]++;
for (int i=head2[u] ; i ; i=edge[i].odr){
int v=edge[i].from;
if (sccno[v]) continue;
dfs2(v);
}
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
scc_cnt=;cas=;
q.clear();
while (m--){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
memset(vis,false,sizeof(vis));
memset(sum,,sizeof(sum));
memset(du,,sizeof(du));
for (int i= ; i<=n ; i++)
if (vis[i]==false){
vis[i]=true;dfs1(i);
q.push_back(i);
} for (int i=n- ; i>= ; i--){
if (!sccno[q[i]]){
scc_cnt++;
// cout<<q[i]<<endl;
dfs2(q[i]);
}
} for (int i= ; i<=cas ; i++){
int x=sccno[edge[i].from],y=sccno[edge[i].to];
if (x==y) continue;
du[x]++;
}
int flag=-,ans;
for (int i= ; i<=scc_cnt ; i++)
if (!du[i]) flag++,ans=sum[i];
if (flag==) printf("%d\n",ans);
else puts("");
return ;
}
Tarjan算法链接也就讲的很清楚了
#include<cstdio>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std; const int M = 1e5 + ;
int head[M],cas,scc_cnt,dfs_clock;
int sccno[M],du[M],sum[M],lowlink[M],pre[M];
stack<int>s; int min(int x,int y){return x<y?x:y;} struct Edge{
int to,next,from;
}edge[M*]; void add(int u,int v)
{
edge[++cas].next=head[u];
edge[cas].to=v;edge[cas].from=u;
head[u]=cas;
} void dfs(int u)
{
pre[u]=lowlink[u]=++dfs_clock;
s.push(u);
for (int i=head[u] ; i ; i=edge[i].next){
int v=edge[i].to;
if (!pre[v]){
dfs(v);
lowlink[u]=min(lowlink[u],lowlink[v]);
}
else if (!sccno[v]){
lowlink[u]=min(lowlink[u],pre[v]);
}
}
if (lowlink[u]==pre[u]){
scc_cnt++;
for ( ; ; ){
int x=s.top();s.pop();
sccno[x]=scc_cnt;
if (x==u) break;
}
}
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
cas=,dfs_clock=,scc_cnt=;
while (m--){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
memset(pre,,sizeof(pre));
memset(lowlink,,sizeof(lowlink));
memset(du,,sizeof(du));
memset(sum,,sizeof(sum));
for (int i= ; i<=n ; i++)
if (!pre[i]) dfs(i);
for (int i= ; i<=n ; i++)
sum[sccno[i]]++;
for (int i= ; i<=cas ; i++){
int u=sccno[edge[i].from],v=sccno[edge[i].to];
if (u==v) continue;
du[u]++;
}
int flag=,ans;
for (int i= ; i<=scc_cnt ; i++)
if (!du[i]) flag++,ans=sum[i];
if (flag==) printf("%d\n",ans);
else puts("");
return ;
}
bzoj 1051 (强连通) 受欢迎的牛的更多相关文章
- BZOJ 1051: [HAOI2006]受欢迎的牛( tarjan )
tarjan缩点后, 有且仅有一个出度为0的强连通分量即answer, 否则无解 ----------------------------------------------------------- ...
- BZOJ 1051: [HAOI2006]受欢迎的牛(SCC)
1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 8172 Solved: 4470[Submit][Sta ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- BZOJ 1051: [HAOI2006]受欢迎的牛 缩点
1051: [HAOI2006]受欢迎的牛 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...
- bzoj 1051: [HAOI2006]受欢迎的牛 tarjan缩点
1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2092 Solved: 1096[Submit][Sta ...
- BZOJ 1051: [HAOI2006]受欢迎的牛 强连通缩点
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1051 题解: 强连通缩点得到DAG图,将图转置一下,对入度为零的点跑dfs看看能不能访问 ...
- 洛谷 P2341 BZOJ 1051 [HAOI2006]受欢迎的牛
题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的——如果A喜 欢B,B喜欢C,那么A也喜欢C ...
- BZOJ 1051: [HAOI2006]受欢迎的牛
Description 一个有向图,求所以能被别的点到达的点的个数. Sol Tarjan + 强连通分量 + 缩点. 缩点以后找强连通分量,缩点,然后当图有且仅有1个出度为1的点时,有答案. Cod ...
- bzoj 1051 [HAOI2006]受欢迎的牛(tarjan缩点)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1051 题解:缩点之后判断出度为0的有几个,只有一个那么输出那个强连通块的点数,否者 ...
随机推荐
- 分享45个android实例源码,很好很强大
分享45个android实例源码,很好很强大 http://www.apkbus.com/android-20978-1-1.html 分享45个android实例源码,很好很强大http://www ...
- maven导入本地jar包
<dependency> <groupId>com.qrcode</groupId> <artifactId>qrcode</artifactId ...
- leetcode 206
206. Reverse Linked List Reverse a singly linked list. 翻转一个单链表. 代码如下: /** * Definition for singly-li ...
- 利用JAVA生成二维码
本文章整理于慕课网的学习视频<JAVA生成二维码>,如果想看视频内容请移步慕课网. 维基百科上对于二维码的解释. 二维条码是指在一维条码的基础上扩展出另一维具有可读性的条码,使用黑白矩形图 ...
- 关于Oracle数据库字符集
我们现在使用的字符集有以下两种: 推荐使用 AL32UTF8,避免以后数据导入导出字符集不同的麻烦. 推荐数据库设置参考图:
- IIS7 IIS8 中多个版本php共存的方法
原文地址: https://blog.cozof.com/pieces/54.shtml 最近又重回.net,用回IIS.然后用到某个php开源项目,需要低版本的php,之前装的一个php5.5不能用 ...
- Python自动获取数据库表结构
Sandman https://sandman.readthedocs.io/en/latest/#
- [转]CSS 表单元素对齐详解
来源:http://blog.sina.com.cn/s/blog_655388ed0100lzyk.html 简单的设置input{vertical-align:middle}即可,完美的: lab ...
- javascript获取当前时间
function getCurrentDate(){ var myDate = new Date(); var month = myDate.getMonth()+1; var day = myDat ...
- UNDO内存结构剖析
UNDO内存结构剖析 一.场景 Oracle的 C事物从早上9:00开始读取A表全部10w行数据,这个而读取需要经历5分钟.在9:01的时候,B事物将A表删除100条记录,那么,当9:05的时候,事物 ...