版权声明:本文为博主原创文章。未经博主同意不得转载。 https://blog.csdn.net/u013480600/article/details/32140501

HDU 3639 Hawk-and-Chicken(强连通分量+缩点)

http://acm.hdu.edu.cn/showproblem.php?pid=3639

题意:

        给你一个有向图,如果从u点能到达v点,那么说u是v的粉丝,如今要你按序输出那些粉丝数目最多的点编号.

分析:

        如果该图是一个强连通图,那么任一点都有n-1个粉丝(即n-1个点能到达它).所以我们把该图缩点变成一个新的DAG图.

        结论:原图中具有最多粉丝的点一定在新图的那些出度为0的点所代表的分量中.

        证明:如果u节点粉丝最多且它所属的分量出度不为0,那么u节点一定是某个节点v的粉丝,所以v的粉丝必定包括了u的全部粉丝加上u本身.所以v的粉丝必定多余u.由此矛盾.

        以下的问题是怎样找新DAG图的每一个节点(所代表分量中的原节点)的最大粉丝数?

该粉丝数=本连通分量的点数-1+本连通分量能通过ß这样的边逆向走到的全部分量的点数和. 所以我们直接建立缩点树的逆图DAG就可以,如果u->v表示u分量将获得v分量的全部节点作为粉丝.所以我们仅仅须要对那几个入度为0的点做DFS就可以.

        每次DFS到一个新节点,该点所代表的分量节点数就都加到sum上去,表示新加了非常多粉丝.最后找最大粉丝值的分量点输出就可以.

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int maxn= 5000+10;
int n,m;
vector<int> G[maxn], G2[maxn];
stack<int> S;
int dfs_clock, scc_cnt;
int pre[maxn],sccno[maxn],low[maxn];
int num[maxn];//表每一个强连通分量各含多少点
int in[maxn];//新DAG的逆图中点的入度
int fan[maxn];//表新DAG中第i个点(分量)有多少粉丝
void dfs(int u)
{
pre[u]=low[u]=++dfs_clock;
S.push(u);
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!pre[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(!sccno[v])
low[u]=min(low[u],pre[v]);
}
if(low[u]==pre[u])
{
scc_cnt++;
num[scc_cnt]=0;
while(true)
{
int x=S.top(); S.pop();
sccno[x]=scc_cnt;
num[scc_cnt]++;
if(x==u) break;
}
}
}
void find_scc(int n)
{
dfs_clock=scc_cnt=0;
memset(pre,0,sizeof(pre));
memset(sccno,0,sizeof(sccno));
for(int i=0;i<n;i++)
if(!pre[i]) dfs(i);
}
bool vis[maxn];
int dfs2(int u)
{
vis[u]=true;
int sum=0;
for(int i=0;i<G2[u].size();i++)
{
int v=G2[u][i];
if(!vis[v]) sum+=num[v]+dfs2(v); //WA-> vis[i] num[i] dfs2(i)
}
return sum;
}
int main()
{
int T; scanf("%d",&T);
for(int kase=1;kase<=T;kase++)
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) G[i].clear();
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
}
find_scc(n); memset(in,0,sizeof(in));
for(int i=1;i<=scc_cnt;i++) G2[i].clear();
for(int u=0;u<n;u++)
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
int x=sccno[u], y=sccno[v];
if(x!=y)
{
in[x]++;
G2[y].push_back(x);//建立DAG的逆图
}
}
memset(fan,0,sizeof(fan)); int max_f=-1;
for(int i=1;i<=scc_cnt;i++)
if(!in[i])
{
memset(vis,0,sizeof(vis)); //WA-> vis数组仅仅在外面初始化1次
fan[i] = num[i]-1+dfs2(i);
max_f=max(fan[i],max_f);
}
bool win[maxn];
memset(win,0,sizeof(win));
for(int i=0;i<n;i++)
if(fan[sccno[i]]==max_f) win[i]=true;
printf("Case %d: %d\n",kase,max_f);
bool first=true;
for(int i=0;i<n;i++)if(win[i])
{
if(first) printf("%d",i), first=false;
else printf(" %d",i);
}
puts("");
}
return 0;
}

HDU 3639 Hawk-and-Chicken(强连通分量+缩点)的更多相关文章

  1. HDU 4635 Strongly connected(强连通分量缩点+数学思想)

    题意:给出一个图,如果这个图一开始就不是强连通图,求出最多加多少条边使这个图还能保持非强连通图的性质. 思路:不难想到缩点转化为完全图,然后找把它变成非强连通图需要去掉多少条边,但是应该怎么处理呢…… ...

  2. HDU 3072 Intelligence System (强连通分量)

    Intelligence System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  3. tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)

    这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...

  4. POJ1236Network of Schools[强连通分量|缩点]

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16571   Accepted: 65 ...

  5. POJ1236Network of Schools(强连通分量 + 缩点)

    题目链接Network of Schools 参考斌神博客 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后 ...

  6. HD2767Proving Equivalences(有向图强连通分量+缩点)

    题目链接 题意:有n个节点的图,现在给出了m个边,问最小加多少边是的图是强连通的 分析:首先找到强连通分量,然后把每一个强连通分量缩成一个点,然后就得到了一个DAG.接下来,设有a个节点(每个节点对应 ...

  7. UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)

    题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...

  8. ZOJ3795 Grouping(强连通分量+缩点+记忆化搜索)

    题目给一张有向图,要把点分组,问最少要几个组使得同组内的任意两点不连通. 首先考虑找出强连通分量缩点后形成DAG,强连通分量内的点肯定各自一组,两个强连通分量的拓扑序能确定的也得各自一组. 能在同一组 ...

  9. POJ2553 The Bottom of a Graph(强连通分量+缩点)

    题目是问,一个有向图有多少个点v满足∀w∈V:(v→w)⇒(w→v). 把图的强连通分量缩点,那么答案显然就是所有出度为0的点. 用Tarjan找强连通分量: #include<cstdio&g ...

随机推荐

  1. python 格式化时间含中文报错: 'locale' codec can't encode character '\u5e74'

    执行下面代码报错: UnicodeEncodeError: 'locale' codec can't encode character '\u5e74' in position 2: Illegal ...

  2. Apache重定向URL

    (1)去除httpd.conf文件中"#LoadModule rewrite_module modules/mod_rewrite.so"前面的"#"号; (2 ...

  3. java——虚拟机、线程

    java虚拟机: 是一台想象中的机器,有自己想象的硬件(处理器.堆栈.寄存器等)以及相应的指令系统. 生命周期:当执行java程序时,虚拟机开始运行,程序结束虚拟机停止.同一台计算机每多运行一个程序, ...

  4. component: resolve => require(['../pages/home.vue'], resolve)

    component: resolve => require(['../pages/home.vue'], resolve) vue 路由的懒加载 import Vue from 'vue' im ...

  5. 解决“<form>提交,CSRF验证失败。请求中止”

    在相应的提交页面,内,添加"{%csrf_token%} ",如: Django工程的app文件的views.py添加屏蔽装饰器,(相应的函数上): from django.vie ...

  6. [转]jQuery页面滚动图片等元素动态加载实现

    本文转自:http://www.zhangxinxu.com/wordpress/?p=1259 一.关于滚动显屏加载 常常会有这样子的页面,内容很丰富,页面很长,图片较多.比如说光棍节很疯狂的淘宝商 ...

  7. php-fpm 进程在云服务器cpu分配不均匀

    8核的云服务器,开了200个php-fpm进程,用top命令查看  大部分进程都在cpu 0 上跑着,导致其他cpu 负载很低,cpu分配不均匀: 使用shell 解决问题: 列出所有php-fpm ...

  8. 自定义Qt组件-通讯模块(P3)

    1.   半双工模式实时检测串口 ComHalfDuplex类是为了解决上位机发送控制指令和下位机发送数据会在半双工RS485总线中产生冲突引起乱码而引入的(v0.010版本引入). 解决冲突的原理主 ...

  9. GOPS 2018全球运维大会上海站 参会感悟梳理

    今天遇到很多优秀的讲师.业界的大伽,很开心 现在把get到的信息梳理一下:(1)想解决性能问题,一定要在缓存上下功夫:[nginx上有好多文章可以做,真是博大精深呢<深入理解Nginx:模块开发 ...

  10. CentOS7中添加新硬盘

      cp /etc/fstab /etc/fstab.bak echo /dev/vdb1 /mnt/disk1 ext4 defaults 0 0 >> /etc/fstab mkdir ...