标签:ack push 删掉 http oid 没有 back memset eof
对于一个节点i来说,如果我们能够先计算出它所有前驱节点的病毒数量,就可以直接推算出它最后的病毒数量了,但是怎么来计算所有前驱节点呢?
这就要从图的性质入手了。我们现在的网络是没有环的,对于任意一个节点i,当它将自己所有的病毒都传送出去之后,它自身的病毒数量就不会改变了。那么我们不妨从没有前驱节点,也就是入度为0的节点开始考虑。
对于这些节点,它并不会再增加病毒数量。那么我们就根据它所关联的连接将病毒分发出去,然后这个节点就没有作用了。那不妨就删掉好了,它所关联的边也删掉,这样图中又会产生一些新的没有入度的节点。这样一直删点,直到所有的点都被删掉,将所有点的病毒数量加起来就是总的病毒数。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const int mod = 142857;
int t,n,m,k,x,u,v,num;
vector<int> G[maxn];
int inDeg[maxn];
int virus[maxn];
queue<int> q;
void topSort()
{
while(!q.empty()) q.pop();
for(int i=1;i<=n;i++) if(!inDeg[i]) q.push(i);
while(!q.empty())
{
int now = q.front();
q.pop();
for(int i=0;i<G[now].size();i++)
{
int nxt = G[now][i];
if(--inDeg[nxt] == 0) q.push(nxt);
virus[nxt]=(virus[nxt]+virus[now])%mod;
}
}
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&k))
{
int ans;
memset(inDeg,0,sizeof(inDeg));
memset(virus,0,sizeof(virus));
for(int i=1;i<=n;i++) G[i].clear();
while(k--)
{
scanf("%d",&x);
virus[x]++;
}
while(m--)
{
scanf("%d%d",&u,&v);
G[u].push_back(v);
inDeg[v]++;
}
topSort();
ans=0;
for(int i=1;i<=n;i++) ans=(ans+virus[i])%mod;
printf("%d\n",ans);
}
}
标签:ack push 删掉 http oid 没有 back memset eof
原文地址:https://www.cnblogs.com/Roni-i/p/9175698.html