• hihoCoder hiho一下 第四十八周 题目1 : 拓扑排序·二


    题意:

      给定一个拓扑图,其中部分结点含有1个病毒,每个结点只要收到病毒就会立即往出边所能到达的点传播,病毒数可叠加,求所有结点的病毒数总和。

    思路:

      根据拓扑的特点,每个入度为0的点肯定不会再被传播病毒,而且会将自己的所有病毒向与其相连的结点传播。那么可以从入度味为0的点着手,逐个删除入度为0的结点,在删除的过程中,更新与其相连的结点的病毒数(即将病毒数累加到该结点),到最后所有结点都没了,各个结点所累积的病毒数的和就是答案。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=100100;
     4 const int mod=142857;
     5 
     6 bool init[N];   //初始是否有病毒
     7 int cnt[N];     //各点的入度
     8 vector< vector<int> >   vect;   //邻接表
     9 int ans[N]; //各个节点的病毒数,不包括其自身初始的那个病毒
    10 
    11 
    12 int cal(int n, int k)
    13 {
    14     vector<int> a;
    15     for(int i=1; i<=n; i++)    if(!cnt[i]) a.push_back(i);  //先装进去初始时入度为0的点
    16 
    17     vector<int> b;
    18     while(!a.empty())
    19     {
    20         b.clear();
    21         for(int i=0; i<a.size(); i++)   //对于每个入度为0的点,更新与其相连的每个点的病毒数
    22         {
    23             for(int j=0; j<vect[a[i]].size(); j++)
    24             {
    25                 int tmp=vect[a[i]][j];
    26                 cnt[tmp]--; //入度减少1
    27                 ans[tmp]=(ans[tmp]+ans[a[i]]+init[a[i]])%mod;   //更新病毒数,包括初始那个病毒
    28                 if(!cnt[tmp])    b.push_back(tmp);  //又一个入度为0的
    29             }
    30         }
    31         a.clear();
    32         if(!b.empty())
    33             a.insert(a.end(), b.begin(), b.end());
    34     }
    35     int sum=0;
    36     for(int i=1; i<=n; i++) //统计
    37         sum=(sum+ans[i])%mod;
    38     sum+=k; //还有初始的病毒
    39     return sum%mod;
    40 }
    41 
    42 
    43 int main()
    44 {
    45     //freopen("e://input.txt","r",stdin);
    46     int k, n, m, a, b;
    47     cin>>n>>m>>k;
    48     vector<int> tmp;
    49     for(int i=0; i<=n; i++)    vect.push_back(tmp); //初始化
    50 
    51     for(int i=0; i<k; i++)  //k个病毒
    52     {
    53         scanf("%d",&a);
    54         init[a]=true;
    55     }
    56     for(int i=0; i<m; i++)  //m个边
    57     {
    58         scanf("%d%d",&a,&b);
    59         vect[a].push_back(b);
    60         cnt[b]++;   //入度数
    61     }
    62     printf("%d
    ",cal(n,k));
    63     return 0;
    64 }
    AC代码
  • 相关阅读:
    关于文件路径的生成
    re模块小结
    logging模块知识点及应用小结
    微信小程序上传图片
    小程序图表插件
    小程序实现多图上传、预览
    微信小程序实现验证码倒计时效果
    微信小程序上传图片,视频及预览
    小程序实现星级打分
    小程序获取系统日期时间
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4544665.html
Copyright © 2020-2023  润新知