<题目链接>

题目大意:

有一群孩子正在玩老鹰抓小鸡,由于想当老鹰的人不少,孩子们通过投票的方式产生,但是投票有这么一条规则:投票具有传递性,A支持B,B支持C,那么C获得2票(A.B共两票),输出最多能获得的票数是多少张和获得最多票数的人是谁?(如果有多个人获得的票数都是最多的,就将他们全部输出)。

解题分析:

不难看出,同一连通分量的所有点得到的票数肯定是相同的,所以我们先将原图进行Tarjan缩点。对于缩完点后的图,我们发现,票数最多的人一定在出度为0的"点"中,因为如果票数最多的点不是出度为0的"点",那么它所到达的那个"点"的票数一定大于当前"点"的票数,这与当前"点"票数最多相矛盾。然后考虑对入度为0的"点"的票数统计,我们可以在缩点后进行重新构图,相互连通的"点"之间建立反边,这样方便DFS统计当前"点"的票数。需要注意的是,当前连通分量中所有的点在当前连通分量中获得的票数为num[now]-1(因为要除去自己),然后再加上以这个点为起点,能够到达所有连通分量的点数,即为这个点能够得到的票数。

 #include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std; #define clr(a,b) memset(a,b,sizeof(a))
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define pb push_back
#define mp make_pair
const int N = 5e3+, M = 3e4+;
int n,m,tot,cnt,cnt1,scc,top,sum;
int head[N],head1[N],low[N],dfn[N],belong[N],stk[N],instk[N],num[N],outdeg[N],vis[N],ans[N];
vector<int>G[N];
struct Edge{
int to,next;
}edge[M],edge1[M];
void init(){
rep(i,,n)G[i].clear();
tot=cnt=cnt1=scc=top=;
clr(head,-);clr(head1,-);clr(low,);clr(num,);clr(ans,);
clr(dfn,);clr(stk,);clr(instk,);clr(belong,);clr(outdeg,);
}
void addedge(int u,int v){
edge[cnt].to=v,edge[cnt].next=head[u];
head[u]=cnt++;
}
void addedge1(int u,int v){ //添加缩点后的反向边
edge1[cnt1].to=v,edge1[cnt1].next=head1[u];
head1[u]=cnt1++;
}
void Tarjan(int u){
dfn[u]=low[u]=++tot;
stk[++top]=u;instk[u]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}else if(instk[v])low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
scc++;
while(true){
int v=stk[top--];
instk[v]=;
belong[v]=scc;
G[scc].pb(v);
if(v==u)break;
}
}
}
void dfs(int u){ //统计以u连通分量为起点能够到达所有的连通分量的点数之和
vis[u]=;
sum+=num[u];
for(int i=head1[u];~i;i=edge1[i].next){
int v=edge1[i].to;
if(!vis[v])dfs(v);
}
}
int main(){
int T,ncase=;scanf("%d",&T);
while(T--){
init();
scanf("%d%d",&n,&m);
rep(i,,m) {
int u,v;scanf("%d%d",&u,&v);
u++,v++;
addedge(u,v);
}
rep(i,,n) if(!dfn[i]){
Tarjan(i);
}
rep(i,,n) num[belong[i]]++; //求出每个连通分量的点数
rep(u,,n) for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
int tmp1=belong[u],tmp2=belong[v];
if( tmp1!=tmp2 ){ //缩点后,进行重新构图,并且添加的是反向边,方便进行票数的统计
addedge1(tmp2,tmp1);outdeg[tmp1]++;
}
}
int mx=-;
rep(i,,scc) if(!outdeg[i]){ //统计所有出度为0的连通分量所能够得到的票数
clr(vis,);
sum=;dfs(i);
ans[i]=sum-; //获得的票数为路径上所有的点数和-1,因为自己不能获得自己的票
mx=max(mx,ans[i]);
}
printf("Case %d: %d\n",++ncase,mx);
bool first=false;
rep(i,,n) if(ans[belong[i]]==mx){ //将所有票数等于最大票数的点输出
if(!first)printf("%d",i-);
else printf(" %d",i-);
first=true;
}puts("");
}
}

2018-12-01

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

  1. 【HDU 5934】Bomb(强连通缩点)

    Problem Description There are N bombs needing exploding. Each bomb has three attributes: exploding r ...

  2. HDU 5934:Bomb(强连通缩点)

    http://acm.hdu.edu.cn/showproblem.php?pid=5934 题意:有N个炸弹,每个炸弹有一个坐标,一个爆炸范围和一个爆炸花费,如果一个炸弹的爆炸范围内有另外的炸弹,那 ...

  3. Codeforces 1027D Mouse Hunt (强连通缩点 || DFS+并查集)

    <题目链接> 题目大意: 有n个房间,每个房间都会有一只老鼠.处于第i个房间的老鼠可以逃窜到第ai个房间中.现在要清理掉所有的老鼠,而在第i个房间中防止老鼠夹的花费是ci,问你消灭掉所有老 ...

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

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

  5. hdu 4635 Strongly connected 强连通缩点

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给你一个n个点m条边的图,问在图不是强连通图的情况下,最多可以向图中添多少条边,若图为原来 ...

  6. hdu 2767 Proving Equivalences 强连通缩点

    给出n个命题,m个推导,问最少添加多少条推导,能够使全部命题都能等价(两两都能互推) 既给出有向图,最少加多少边,使得原图变成强连通. 首先强连通缩点,对于新图,每一个点都至少要有一条出去的边和一条进 ...

  7. HDU 3639 Hawk-and-Chicken(良好的沟通)

    HDU 3639 Hawk-and-Chicken 题目链接 题意:就是在一个有向图上,满足传递关系,比方a->b, b->c,那么c能够得到2的支持,问得到支持最大的是谁,而且输出这些人 ...

  8. HDU 1827 Summer Holiday(强连通)

    HDU 1827 Summer Holiday 题目链接 题意:中文题 思路:强连通缩点,每一个点的权值为强连通中最小值,然后入度为0的点就是答案 代码: #include <cstdio> ...

  9. poj2553 强连通缩点

    The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 10114   Accepted: ...

随机推荐

  1. swift 学习- 23 -- 扩展

    // 扩展 就是为一个已有的 类, 结构体, 枚举, 或者 协议类型添加新功能, 这包括在没有权限获取 原始代码的情况下 扩展类型的能力 (即 逆向建模), 扩展和 OC 中的分类类似, (与 OC ...

  2. Confluence 6 WebDAV 禁用严格路径检查

    如果你在你的 WebDAV 客户端发现了一些不正常的现象,例如文件夹在 Confluence 中是存在的,但是在你客户端下载的文件中就不存在了.你可以禁用  WebDAV 插件中的严格路径检查选项,这 ...

  3. Confluence 6 新 Confluence 安装配置一个数据源连接

    如果在你的 Tomcat 中配置了数据源,并且Confluence 设置指南在安装的时候检测到这个配置的时候,配置数据源的选项将会提供给你进行配置.入股你希望使用数据源,请参考下面的配置. 1. 停止 ...

  4. Confluence 6 配置避免管理员联系表单垃圾

    你可以配置 Confluence 使用验证码(Captcha)来避免垃圾内容发送给 Confluence 管理员.有关管理员联系表单验证码的内容在全站验证码设置中进行配置,相关的文档请参考 Confi ...

  5. 团队开发工具git常用命令

    Git 常用命令 Git配置 git config --global user.name "storm" git config --global user.email " ...

  6. Linux磁盘与文件系统管理笔记

    ### Linux磁盘与文件系统管理 linux 最传统的文件系统格式是EXT2,centos7 默认文件系统是xfs(日志式文件系统) 磁盘的组成: 盘片 机械手臂 主轴马达 (机械硬盘) 磁盘格式 ...

  7. 整合Flask中的目录结构

    一.SQLAlchemy-Utils 由于sqlalchemy中没有提供choice方法,所以借助SQLAlchemy-Utils组件提供的choice方法 import datetime from ...

  8. CentOS 7 安装JDK环境

    1.JDK下载地址:https://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase8-2177648.html ...

  9. 【python】gevent协程例子

    说在前面:用协程还是多线程需要仔细考量.我在做实验时请求了100w个ip,分别用pool为1000的协程和64个线程来跑,结果是多线程的速度是协程的10倍以上. 一个简单的协程例子 #!/usr/bi ...

  10. Imperial roads 非严格次小生成树

    cf测评姬比uva快了五倍... /* 不管这条边是不是在mst上,直接跑lca求出路径上的最大边w即可 ans=mst-w+dist(u,v) */ #include<bits/stdc++. ...