zoukankan      html  css  js  c++  java
  • HDU 3639 HawkandChicken

      题意:孩子们在幼儿园非常喜欢老虎抓小鸡的游戏。但是有一个比较大的问题:每一个人都想演老虎的角色。
    因此老师提出一个建议:选举。每个孩子手里面有一些漂亮的手帕,如果他认为某个人适合老虎的角色,
    他就拿出一个手帕给他,也就是说得到手帕就是得到支持的一票。注意支持是可以传递的。最后得到支持
    票数最多的人将扮演老虎的角色。(注意:如果A赢得B的支持,A只能得到B的一票,不管B有多少票,既是说A = B得到的选票 + 1,A不能投自己一票)如果多个人获得同样多的票,我们称他们都是赢家。
      例子:三个人 A,B,C。A拿一个手帕给B, B拿一个手帕给C, 因此 C得到2个手帕,C被选为扮演老虎。
    先输入一个测试样例数T,然后输入n 和 m,n是人数(0 ~ n - 1),下面是m行 A B (A!= B)代表A支持B。
    输出最大得票数,和得票者。

      

      这题我做的时候求强连通分支、缩点都很顺利,后来还是WA了,后来看了别人的代码才发现我的问题:在计算每个点(已缩)的最大值除了问题。见下图.

      缩完点有可能出现图中的情况(因为上图并不是强连通的,只是个弱连通,所以有可能出现),在我原来的程序中DFS计算点4的票数时会把点3 的贡献给忽略了,从而点5的值也就错了。正确的做法是按照上图建个逆图(边的方向相反,如下图),这样从逆图的根(准确来讲是入度为0的点,因为这样的点在图中可能不只一个)开始DFS计算根的值,就能方便正确地得到点5 的值了。

      至于为什么要选择从入度为0的点开始DFS并比较这些点的值的大小(换句话说为什么答案一定出自这些点)?如果假设最大值存在于一个入度不为0的分量中,那么连接这个分量的 那个分量票数支持肯定大于这个分量,假设不成立。

    逆向图DFS的伪代码:

    void dfs(int u)
    {
       num[u]=n[u];
    for each(u,v) in 逆向图 { dfs(v); num[u]+=num[v]; } }
  • 相关阅读:
    NHibernate初学二之简单执行SQL及HQL、Linq
    Socket通信常用方法
    Android中自定义属性的使用
    四种常见的 POST 提交数据方式
    关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
    1、memcache的守护进程启动方式(2017-8-10)
    c++封装简单日志操作
    关于vector的内存释放
    Linux进程通信-共享内存
    Linux进程通信总结
  • 原文地址:https://www.cnblogs.com/wuminye/p/2960381.html
Copyright © 2011-2022 走看看