• 2016"百度之星"


      分析:首先,利用贪心可知,如果要所有人的分数和最高,需要把序号大的优先放在前面。其次,对于a的前面不能为b,那么只能a在b前面了,那么就建立一条从a到b的边,并且b的入度加1。然后就是拓扑排序了。要分数最高,则把哪些入度为0的点(他们不需要有哪些人一定要在他们前面,最自由)丢进优先队列,然后就可以实现把序号大的尽量放在前面而且满足题意了。

      具体见代码:

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 #include <vector>
     5 #include <queue>
     6 using namespace std;
     7 typedef long long ll;
     8 
     9 vector<int> G[100000+5];
    10 int in[100000+5],val[100000+5];
    11 int n,m;
    12 void solve()
    13 {
    14     int sit=1;
    15     priority_queue<int> Q;
    16     for(int i=1;i<=n;i++) if(!in[i]) Q.push(i);
    17     while(!Q.empty())
    18     {
    19         int x=Q.top();Q.pop();
    20         val[sit++]=x;
    21         for(int i=0;i<G[x].size();i++)
    22         {
    23             int v = G[x][i];
    24             in[v]--;
    25             if(!in[v]) Q.push(v);
    26         }
    27     }
    28 }
    29 int main()
    30 {
    31     int T;
    32     scanf("%d",&T);
    33     while(T--)
    34     {
    35         scanf("%d%d",&n,&m);
    36         for(int i=1;i<=n;i++) G[i] .clear();
    37         memset(in,0,sizeof(in));
    38         memset(val,0,sizeof(val));
    39         while(m--)
    40         {
    41             int u,v;
    42             scanf("%d%d",&u,&v);
    43             G[u].push_back(v);
    44             in[v]++;
    45         }
    46         solve();
    47         int minn=100000+5;
    48         ll ans=0;
    49         for(int i=1;i<=n;i++)
    50         {
    51             minn=min(minn,val[i]);
    52             ans+=(ll)minn;
    53         }
    54         printf("%I64d
    ",ans);
    55     }
    56     return 0;
    57 }

      

  • 相关阅读:
    vim编辑器
    centos7启动顺序加密的问题
    centos7进入单用户模式
    centos7修改默认运行级别的变化
    C#构建DataTable(转)
    策略模式简介
    简单工厂模式(转)
    NPOI导Excel样式设置(转)
    VS2012启用angularjs智能提示Intelligence
    WebForm页面间传值方法(转)
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5516652.html
Copyright © 2020-2023  润新知