HDU 3639 Hawk-and-Chicken(强连通分量+缩点)
版权声明:本文为博主原创文章。未经博主同意不得转载。 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(强连通分量+缩点)的更多相关文章
- HDU 4635 Strongly connected(强连通分量缩点+数学思想)
题意:给出一个图,如果这个图一开始就不是强连通图,求出最多加多少条边使这个图还能保持非强连通图的性质. 思路:不难想到缩点转化为完全图,然后找把它变成非强连通图需要去掉多少条边,但是应该怎么处理呢…… ...
- HDU 3072 Intelligence System (强连通分量)
Intelligence System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)
这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...
- POJ1236Network of Schools[强连通分量|缩点]
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16571 Accepted: 65 ...
- POJ1236Network of Schools(强连通分量 + 缩点)
题目链接Network of Schools 参考斌神博客 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后 ...
- HD2767Proving Equivalences(有向图强连通分量+缩点)
题目链接 题意:有n个节点的图,现在给出了m个边,问最小加多少边是的图是强连通的 分析:首先找到强连通分量,然后把每一个强连通分量缩成一个点,然后就得到了一个DAG.接下来,设有a个节点(每个节点对应 ...
- UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)
题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...
- ZOJ3795 Grouping(强连通分量+缩点+记忆化搜索)
题目给一张有向图,要把点分组,问最少要几个组使得同组内的任意两点不连通. 首先考虑找出强连通分量缩点后形成DAG,强连通分量内的点肯定各自一组,两个强连通分量的拓扑序能确定的也得各自一组. 能在同一组 ...
- POJ2553 The Bottom of a Graph(强连通分量+缩点)
题目是问,一个有向图有多少个点v满足∀w∈V:(v→w)⇒(w→v). 把图的强连通分量缩点,那么答案显然就是所有出度为0的点. 用Tarjan找强连通分量: #include<cstdio&g ...
随机推荐
- tomcat 虚拟目录配置appBase和docBase的区别
先看server.xml文件host配置 <Host name="localhost" appBase="webapps" 可以修改成自己想 ...
- 8-----BBS论坛
BBS论坛(八) 8.1.发送邮箱验证码功能 (1)cms/resetemail.html {% from 'common/_macros.html' import static %} {% bloc ...
- cannot focus element解决方案
If you enconter error "cannot focus element" when using Selenium+Python in Chrome to input ...
- RTT设备与驱动之PWM
这里将PWM当成一个设备:PWM简介 上图是一个简单的 PWM 原理示意图,假定定时器工作模式为向上计数,当计数值小于阈值时,则输出一种电平状态,比如高电平,当计数值大于阈值时则输出相反的电平状态,比 ...
- css3制作梯形导航
/*HTML*/<div class="nav"> <a href="javascript:;">首页</a> <a ...
- PlayMaker 设置颜色 Set Materia lColor
1. 指定一个游戏对象,Color处设为红色,执行这个行为后就把游戏对象的材质变为了红色: 2. Color也可以使用一个弄好的Color类型的变量,如下图:Color处用了一个提前设置好的变量
- Unity 改变游戏对象的Scale引起的不好结果
1. 当一个游戏对象的中心(它的x,y,z的交点) 不在它的正中间时,改变它的Scale时它的中心也会变的. 如图:这是用PlayMkaer做的,胶囊体碰到瓶子瓶子会碎,会在瓶子的中心位置那生成一个 ...
- 摄像机模型 (Camera Model)
摄像机通过成像透镜将三维场景投影到摄像机二维像平面上,这个投影可用成像变换描述,即摄像机成像模型.摄像机成像模型有不同描述方式,本节首先介绍机器视觉中的常用坐标系,然后介绍摄像机的线性模型和非线性模型 ...
- Oracle SQL Tuning Advisor 测试
如果面对一个需要优化的SQL语句,没有很好的想法,可以先试试Oracle的SQL Tuning Advisor. SQL> select * from v$version; BANNER --- ...
- dos文件格式转换为Unix文件格式
做linux开发的,一般还是在windows上装个虚拟机,在windows上开发, 所以就会出现dos文件与unix文件格式不一致,当windows上的文件在linux上用的时候,经常在每行的末尾会出 ...