HDU3639 Hawk-and-Chicken_kids in kindergarten enjoy playing a game called h-程序员宅基地

技术标签: dfs  dfs-bfs  tarjan  巧妙的做法  缩点  

传送门
Problem Description
Kids in kindergarten enjoy playing a game called Hawk-and-Chicken. But there always exists a big problem: every kid in this game want to play the role of Hawk.
So the teacher came up with an idea: Vote. Every child have some nice handkerchiefs, and if he/she think someone is suitable for the role of Hawk, he/she gives a handkerchief to this kid, which means this kid who is given the handkerchief win the support. Note the support can be transmitted. Kids who get the most supports win in the vote and able to play the role of Hawk.(A note:if A can win support from B(A != B) A can win only one support from B in any case the number of the supports transmitted from B to A are many. And A can’t win the support from himself in any case.
If two or more kids own the same number of support from others, we treat all of them as winner.
Here’s a sample: 3 kids A, B and C, A gives a handkerchief to B, B gives a handkerchief to C, so C wins 2 supports and he is choosen to be the Hawk.
Input
There are several test cases. First is a integer T(T <= 50), means the number of test cases.
Each test case start with two integer n, m in a line (2 <= n <= 5000, 0 < m <= 30000). n means there are n children(numbered from 0 to n - 1). Each of the following m lines contains two integers A and B(A != B) denoting that the child numbered A give a handkerchief to B.
Output
For each test case, the output should first contain one line with “Case x:”, here x means the case number start from 1. Followed by one number which is the total supports the winner(s) get.
Then follow a line contain all the Hawks’ number. The numbers must be listed in increasing order and separated by single spaces.
Sample Input
2
4 3
3 2
2 0
2 1

3 3
1 0
2 1
0 2
Sample Output
Case 1: 2
0 1
Case 2: 2
0 1 2
Author
Dragon
Source
2010 ACM-ICPC Multi-University Training Contest(19)——Host by HDU

题目描述

有n个点,m条边,求出能到某一个点的其他点最多的点,以及能到这个(些)点的其他点的点数。

题解

直接做显然没法做,应该先tarjan缩点后再在DAG上进行计算。
一种好的方法是缩点后将原先的边倒过来进行计算,这样能避免一种不容易被考虑到的情况:
这里写图片描述
在这个图中,答案应该是4号点,这是显然的;但是在计算能到达4号点的点数时,如果直接算会导致算重,但如果反过来算就会避免这种情况。
ps:大家一定要在输出点的时候单独输出最后一个点,否则如果在最后出现多余的空格的话会导致PE!(也许可以尝试putchar一个退格键?反正我没试过)

CODE:

#include<cstdio>
#include<cstring>
const int N=5005;
const int M=3e4+10;
struct edge
{
    int nxt,to;
}a[M],e[M<<1];
int head[N],Head[N];
int dfn[N],low[N];
int block[N],size[N],in[N];
int s[N],top;
bool instack[N],isans[N];
int vis[N],Ans[N];
int tmp[N];
int T,n,m,x,y,num,Num,tot,Time,Tot,ans,ansnum;
inline int min(const int &a,const int &b){return a<b?a:b;}
inline void add(int x,int y)
{
    a[++num].nxt=head[x],a[num].to=y,head[x]=num;
}
inline void add2(int x,int y)
{
    e[++Num].nxt=Head[x],e[Num].to=y,Head[x]=Num;
}
void dfs(int now)
{
    dfn[now]=low[now]=++Time;
    instack[now]=1;
    s[++top]=now;
    for(int i=head[now];i;i=a[i].nxt)
      if(!dfn[a[i].to])
      {
        dfs(a[i].to);
        low[now]=min(low[now],low[a[i].to]);
      }
      else if(instack[a[i].to]) low[now]=min(low[now],dfn[a[i].to]);
    if(low[now]==dfn[now])
    {
        int tmp;
        tot++;
        do tmp=s[top--],instack[tmp]=0,block[tmp]=tot,size[tot]++;
        while(tmp!=now);
    }
}
int Dfs(int now,int root)
{
    int ans=size[now];
    for(int i=Head[now];i;i=e[i].nxt)
      if(vis[e[i].to]!=root) vis[e[i].to]=root,ans+=Dfs(e[i].to,root);
    return ans;
}
int main()
{
    scanf("%d",&T);
    for(int k=1;k<=T;k++)
    {
        memset(in,0,sizeof(in));
        memset(dfn,0,sizeof(dfn));
        memset(vis,0,sizeof(vis));
        memset(size,0,sizeof(size));
        memset(head,0,sizeof(head));
        memset(Head,0,sizeof(Head));
        memset(isans,0,sizeof(isans));
        num=Num=tot=Tot=Time=ans=ansnum=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
          scanf("%d%d",&x,&y),add(x+1,y+1);
        for(int i=1;i<=n;i++)
          if(!dfn[i]) dfs(i);
        for(int j=1;j<=n;j++)
          for(int i=head[j];i;i=a[i].nxt)
            if(block[j]!=block[a[i].to]) add2(block[a[i].to],block[j]),in[block[j]]++;
        for(int i=1;i<=n;i++)
          if(!in[i])
          {
            int tmp=Dfs(i,i);
            if(tmp>ans) Ans[Tot=1]=i,ans=tmp;
            else if(tmp==ans) Ans[++Tot]=i;
          }
        for(int i=1;i<=Tot;i++)
          isans[Ans[i]]=1;
        printf("Case %d: %d\n",k,ans-1);
        for(int i=1;i<=n;i++)
          if(isans[block[i]]) tmp[++ansnum]=i-1;
        for(int i=1;i<ansnum;i++)
          printf("%d ",tmp[i]);
        printf("%d\n",tmp[ansnum]);
    }
    return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/SLYZ_wumingshi/article/details/72811727

智能推荐

java实现打印功能-程序员宅基地

文章浏览阅读7.5w次,点赞22次,收藏75次。前言在我们的实际工作中,经常需要实现打印功能。但由于历史原因,Java 提供的打印功能一直都比较弱。实际上最初的 jdk 根本不支持打印,直到 jdk1.1 才引入了很轻量的打印支持。所以,在以前用 Java/Applet/JSP/Servlet 设计的程序中,较复杂的打印都是通过调用 ActiveX/OCX 控件或者 VB/VC 程序来实现的,非常麻烦。实际上,SUN 公司也一直致力于 _java实现打印

关于用Class.forName(“com.mysql.jdbc.Driver”)注册数据库驱动_<% try { // 加载数据库驱动,注册到驱动管理器 class.forname("com.my-程序员宅基地

文章浏览阅读1.5k次。传统的使用jdbc来访问数据库的流程为: Class.forName(“com.mysql.jdbc.Driver”); String url = “jdbc:mysql://localhost:3306/test?user=root&password=123456″; Connection con = DriverManager.getConnection(url); Statem_<% try { // 加载数据库驱动,注册到驱动管理器 class.forname("com.mysql.jd</div>

modbus读取保持寄存器实例_modbus读取寄存器数据-程序员宅基地

文章浏览阅读8.4k次,点赞4次,收藏7次。读取103-110的实例,一共读取3个寄存器请求: 03 00 6B 00 0303 :功能码,表示读取保存寄存器006B,十六进制表示107,从107开始往后读取0003,十六进制表示读取3个寄存器响应: 03 06 02 2B 00 00 00 6403 功能码,直接复制请求的06 表示后面的数据有多少个字节..._modbus读取寄存器数据

windows java服务启动脚本_windows java启动脚本-程序员宅基地

文章浏览阅读1k次。start javaw -jar zsfx-api-0.0.1-SNAPSHOT.jarxxx.bat_windows java启动脚本

CTF-web Xman-2018 010 editor 简单使用_010editor底部窗口如何调出来-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏10次。在学msic时候,发现010是一个非常好用的工具,除了是一个查看和修改文件的编译器外,还有很多自带的脚本可以帮助我们辅助分析文件格式 这是他的主界面,可以通过选项改变观察方式在插入点的位置直接输入就可以覆盖原来的数据,点击delet就可以删除前一字节一些基本的查找 删除自然不在话下,就不多说了脚本安装一般可以识别的格式会自动提醒你安装相应的脚本,否则需要自己手动..._010editor底部窗口如何调出来

win7 to win10_windows7 to window 10-程序员宅基地

文章浏览阅读749次。upgrade:https://www.microsoft.com/en-us/software-download/windows10win10 iso download:http://www.iwin10.com/xiazai/826.html_windows7 to window 10

随便推点

再记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)-程序员宅基地

文章浏览阅读173次。在此之前项目有发生过两次类似的状况,都得以解决,但最近又会发现偶尔CPU会跑满,虽然之前使用过WinDbg解决过两次问题但人的记忆是不可靠的,今天处理同样问题的时候还是遇到了一些障碍,这一次希望可以记录的更全面些。 上两次的博文链接:记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)、EntityFramework中的线程安全,又是Dictionary。 首先请大家不要喷我..._entityframework线程安全

vb.net 接口POST方式传参数提交返回值_vb.net webclient post-程序员宅基地

文章浏览阅读1k次。Try Dim WebClientObj As New System.Net.WebClient() Dim PostVars As New System.Collections.Specialized.NameValueCollection() 'URL _vb.net webclient post

解决EditText 键盘imeOptions 设置后与换行冲突问题-程序员宅基地

文章浏览阅读604次。解决EditText 键盘imeOptions 设置后与换行冲突问题EditText imeOptions 设置必然需要设置singleLines=true 或者设置 inputType=“textXXX”, 这就不太符合需求。 解决办法:继承 EditTextpublic InputConnection onCreateInputConnection(EditorInfo outAttrs) { InputConnection connection = super.onCreate_解决edittext 键盘imeoptions 设置后与换行冲突问题

Pycharm配置Anaconda中的Tensorflow环境详解_pycharm配置anaconda的tensorflow-程序员宅基地

文章浏览阅读4.9w次,点赞6次,收藏21次。Pycharm配置Anaconda中的Tensorflow环境详解1.打开Pycharm软件,新建工程,点击File->Default Settings->Project Interprete2.默认的应该是anaconda下的python环境,我们点击Existing enviroment:3.点击右边...添加:4.找到anaconda目录下的envs,因为我装了两次Tensorfnslow(每创建一个环境,就可以安装一个,不冲突),所以可以看到我这边会有两个这种_pycharm配置anaconda的tensorflow

符号扩展,零扩展与符号缩减-程序员宅基地

文章浏览阅读1.6w次,点赞23次,收藏101次。1. 符号位扩展,零扩展,符号位缩减1.1 符号位扩展高级程序设计语言允许程序员使用包含不同大小整数的对象表达式。那么,当一个表达式的两个操作数大小不同时,有些语言会报错,有些语言则会自动将操作数转换成一个统一的格式。这种转换是有代价的,因此如果你不希望编译器在你不知情的情况下自动加入各种转换到原本非常完美的代码中,你就需要掌握编译器如何处理这些表达式。以-64为例,其8位的二进制补码(1100 0_符号扩展

【引用】DMA内存申请--dma_alloc_coherent_dma引用-程序员宅基地

文章浏览阅读2.8k次。在项目驱动过程中会经常用到dma传输数据,而dma需要的内存有自己的特点,一般认为需要物理地址连续,并且内存是不可cache的,在linux内核中提供一个供dma所需内存的申请函数dma_alloc_coheren. 如下所述:dma_alloc_coherent()dma_alloc_coherent() -- 获取物理页,并将该物理页的总线地址保存于dma_handle,返回该物理页的虚拟地址_dma引用

推荐文章

热门文章

相关标签