题目链接:

题目解析:
题目数据: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. VMware Workstation Pro 14.1.1 正式版
  2. Java集合篇:fail-fast机制 与 fail-safe
  3. 5 拦截器拦截请求路由_手写简易版axios拦截器,实现微信小程序wx.request的封装与拦截...
  4. java ean13 条形码_【教程】Spire.Barcode 教程:如何在C#中创建EAN-13条码
  5. echarts map 点击地图区域变色_pyecharts 地图可视化
  6. 如果使用SQLExpress 2005时要求'sp_configure 'User instances enabled''
  7. linux CP命令覆盖不提示方法
  8. java 枚举 类 enum
  9. 加密狗厂商及工作原理介绍
  10. mysql省市区县街道
  11. USBCAN上位机软件的使用
  12. w10连接远程计算机控制,win10远程电脑怎么设置_win10通过远程桌面控制其他电脑的方法...
  13. cwRsync文件同步
  14. 从仿射变化到STN网络
  15. mysql 错误码1236,MySQL错误:Last_IO_Errno:1236处理办法
  16. 微信会员卡展示条形码
  17. 技嘉主板u盘启动快捷键介绍
  18. 微信公众号申请到开发环境搭建
  19. 使用Android模拟机开发调试移动端页面
  20. rsi红绿多空波段副图指标 rsi指标公式趋势,兼容通达信公式

热门文章

  1. 人工智能--不确定性推理概述
  2. 2019上半年个人成长复盘
  3. 重磅发布|主机安全联动蜜罐解决方案助力大型攻防演练
  4. 几种高效电路分析方法
  5. 1篇SCI二区+4篇一类可定A档博士!110万房补,享副教授甚至教授待遇!
  6. 微信小程序授权登录详细解析
  7. sqlite3 error: database is locked
  8. 一分钟教程:注册谷歌邮箱
  9. 2018年全国多校算法寒假训练营练习比赛(第三场)---I---题(皮克公式)
  10. 手机vnc远程控制软件,2步完成手机vnc远程控制软件的安装和使用