题目链接:

题目解析:
题目数据:100%的数据N<=10000,M<=50000;
显然这个图里面会有环,而我们可以做的是:判断这个点是否是其它点的子节点;
因此:要把这个图转化为树;
用到Trajan算法;
在这道题中:可能会出现如下情况:
a-->b<--c;||V(箭头)d就是有a ,c这两个入度为0的点;所以要用一个for循环,控制Trajan算法的进行,保证所有的点都已经更新;for(int i=1;i<=n;i++){if(!dfn[i]) {tarjan(i);}}

如果是第一次接触Trajan算法,推荐你阅读我的另一篇博客,里面有一些对于该算法所使用变量的注释
博客链接
下面接着分析:

将图更新为树后,如何寻找所有点的子节点;
第一种:树形dp的方法
第二种:直接判断树中,出度为0的点有几个,如果有一个,输出对应的点包含几个原始点;
有过有多个,直接输出0;
第一种:
树形dp如何写,
a-->b<--c;||V(箭头)db被父节点更新时,判断b是否已经被更新过,如果没被更新(也就是要第一次更新)那么就把自身的值加上,传递给d的值,也就是b目前的值;如果b已经被更新,那么b所有的子节点也一定被更新了,这是b增加的只是父节点给它更新的值b传给子节点的值,也是它的父节点传给它的值;详细看代码。
#include<map>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int num=10010;
/*---------------------*/
struct node{int u,v,next;bool flag;
}e[num*5];
int head[num],ip0[num],cnt;
map<pair<int,int>,bool>mp;
int head2[num],ip[num],op[num],cnt2;
/*---------------------*/
int dfn[num],low[num],ind,stack[num],t,f[num],cnt3,w[num],all;
bool vis[num];
/*---------------------*/
int n,m,ans,dp[num];
/*---------------------*/
void int_i(void)
{cnt=-1;mp.clear();memset(ip0,0,sizeof(ip0));memset(head,-1,sizeof(head));cnt2=-1;memset(ip,0,sizeof(ip));memset(op,0,sizeof(op));memset(head2,-1,sizeof(head2));ind=0;memset(dfn,0,sizeof(dfn));memset(low,-1,sizeof(low));memset(vis,0,sizeof(vis));t=0;memset(stack,0,sizeof(stack));cnt3=0;memset(f,0,sizeof(f));memset(w,0,sizeof(w));all=n;ans=0;memset(dp,0,sizeof(dp));return ;
}
void addedge(int u,int v)
{e[++cnt].u=u;mp[make_pair(u,v)]=true;e[cnt].v=v;e[cnt].flag=false;e[cnt].next=head[u];head[u]=cnt;ip0[v]++;return ;
}
void addedge2(int u,int v)
{e[++cnt2].u=u;e[cnt2].v=v;e[cnt2].flag=false;e[cnt2].next=head2[u];head2[u]=cnt2;op[u]++;ip[v]++;return ;
}
void tarjan(int u)
{int v;dfn[u]=low[u]=++ind;stack[++t]=u;vis[u]=true;for(int i=head[u];i!=-1;i=e[i].next){if(e[i].flag) continue;v=e[i].v;//printf("v==%d\n",v);e[i].flag=true;if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);}else if(vis[v]){low[u]=min(low[u],dfn[v]);}}//printf("u==%d,dfn==%d,low==%d\n",u,dfn[u],low[u]);if(dfn[u]==low[u]){cnt3++;do{v=stack[t--];vis[v]=false;f[v]=cnt3;w[cnt3]++;//printf("cnt3==%d,v==%d,w==%d\n",cnt3,v,w[cnt3]);}while(v!=u);}return ;
}
void dfs(int u,int f,int c)
{int v;for(int i=head2[u];i!=-1;i=e[i].next)//注意这里是head2,不是head,不要写混了;{v=e[i].v;if(v==f) continue;if(dp[v]==0) {//当前结点第一次更新,加上自身的dp[v]=w[v]+c;dfs(v,u,dp[v]);//如果当前结点为0,那么它所在的这条路径没有更新过它的子节点}else if(dp[v]!=0){dp[v]+=c;dfs(v,u,c);}if(dp[v]==all) ans+=w[v];//这里要写w[v],不能写+1;因为可能满足条件的一个点,//包含了许多点}return ;
}
//第二种方法:
void solve(void)
{int c=0,u=0;for(int i=1;i<=cnt3;i++){if(op[i]==0){c++;u=i;}}if(c==1){ans=w[u];}elseans=0;return ;
}
int main()
{int u,v;while(scanf("%d%d",&n,&m)!=EOF){int_i();for(int i=1;i<=m;i++){scanf("%d%d",&u,&v);if(!mp[make_pair(u,v)])addedge(u,v);}for(int i=1;i<=n;i++){if(!dfn[i]) {tarjan(i);}}for(int i=0;i<=cnt;i++){u=e[i].u;v=e[i].v;if(f[u]!=f[v]){// printf("f[u]==%d,f[v]==%d\n",f[u],f[v]);addedge2(f[u],f[v]);//(f[u],f[v]) ;not (u,v)}}if(cnt3==1)//说明原图只有一个点或只有一个环{printf("%d\n",n);continue;}for(int i=1;i<=cnt3;i++){if(ip[i]==0){//printf("fa===%d\n",i);dfs(i,-1,w[i]);}}//for(int i=1;i<=cnt3;i++)//   printf("dp==%d\n",dp[i]);//第二种方法://solve();printf("%d\n",ans);}return 0;
}
/*3 31 22 12 34 31 32 33 4*/

受欢迎的牛+Trajan缩点+树形dp相关推荐

  1. bzoj1051 [HAOI2006]受欢迎的牛 tarjan缩点

    题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的"喜欢"是可以传递的--如果A喜 欢B,B喜 ...

  2. 中石油训练赛 - Plan B(点双缩点+树形dp)

    题目大意:给出一张 n 个点 m 条边的无向连通图,现在有某些点被标记了,问能否通过删除某个未被标记的点,使得删除该点后的数个互不相交的连通块中,至少存在一个联通块中不含有被标记的点 题目分析:首先不 ...

  3. CodeForces - 1220E Tourism(边双缩点+树形dp)

    题目链接:点击查看 题目大意:给出一个由n个点和m条边构成的无向图,每个点都有一个权值,现在给出起点st,问从起点出发,如何规划路线可以使得途径的权值最大,唯一的约束是一条边不能连续经过,比如当前从u ...

  4. 牛客wannafly27 C 树形dp

    Description "你,你认错人了.我真的,真的不是食人魔."–蓝魔法师 给出一棵树,求有多少种删边方案,使得删后的图每个连通块大小小于等于k,两种方案不同当且仅当存在一条边 ...

  5. 解题报告:luogu P2341 受欢迎的牛(Tarjan算法,强连通分量判定,缩点,模板)

    题目链接:洛谷 受欢迎的牛 基本上算是一道模板题 根据题意,如果有环,意味着这个环里的牛都互相喜欢 我们可以先求出环,然后把每一个环都看作一个点,这样整个图就变成了一个DAG(有向无环图) 看有几个点 ...

  6. BZOJ 1051 受欢迎的牛(Tarjan缩点)

    1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4573  Solved: 2428 [Submit][S ...

  7. 洛谷P2341 [HAOI2006]受欢迎的牛 (Tarjan,SCC缩点)

    P2341 [HAOI2006]受欢迎的牛|[模板]强连通分量 https://www.luogu.org/problem/P2341 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就 ...

  8. 【BZOJ1051】受欢迎的牛,tarjan缩点重构图

    Time:2016.05.18 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: (自己不必认为自己受欢迎) tarjan缩点然后重构图 一个强连通分量里肯定是相互认为受欢迎的 重构图 ...

  9. BZOJ 1051 受欢迎的牛 缩点

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1051 题目大意: 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数( ...

  10. 【tarjan缩点】受欢迎的牛

    P2341 [HAOI2006]受欢迎的牛 缩点令我快乐哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 一遍过编译一遍A哈哈哈哈哈哈开心快乐哈哈哈哈哈哈哈哈哈哈 好吧其实很简单 因为牛的爱慕具有传递性(爱牛及牛?? ...

最新文章

  1. JavaScript学习之一:采用哪种方式定义类或对象?
  2. Windows编程-- 用户方式中线程的同步---关键代码段(临界区)
  3. Linux rpm 命令
  4. 新疆计算机一级考试试题手机软件,新疆维吾尔自治区计算机一级考试理论题库(最新最完整)...
  5. asp.net 检测访问者是iphone,android,web(摘录)
  6. jq 自动滑动轮换(向后插入小块)
  7. 去除Many2one字段的“创建并编辑”选项
  8. 第九天 面试失败了。。。。
  9. 怎样用DNSPod做负载均衡?
  10. PDF转EPUB格式电子书经验总结
  11. GOBY--一款攻击面测绘工具的使用
  12. Oracle 调优确定存在问题的SQL
  13. 实现网页购物车功能,完成基本的商品价格计算等功能
  14. 好用的在线二维码生成器网站PHP源码
  15. 【JqGrid】JqGrid API 中文说明及用法
  16. 使用IBM InfoSphere Guardium REST API
  17. Rust之包,箱和模块管理(四):用use关键字引用其他包
  18. 说说12306,呆在深圳就只能一直抢票
  19. LANMT架构搭建jspxcms
  20. 关于ubuntu下的c++编译

热门文章

  1. 齐岳|马钱苷酸小麦麦清白蛋白纳米粒|雷公藤红素乳清白蛋白纳米粒Celastrol-whey protein
  2. javascript 模块加载器——coolie
  3. 大数据常用命令-超全
  4. 量化新手初识Campisi模型
  5. vestacp调整php.ini,VestaCP中roundcube的SMTP配置方法
  6. Word 2016插入公式快捷键
  7. MATLAB多元线性拟合——03
  8. vbs表白小程序,女生同意才能关掉。
  9. 互联网人吐槽互撕系列漫画 要来啦~
  10. 网站seo运营中如何精确预测热门搜索关键词?