题目链接:
http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804
题解:
用拓扑的思想去进行转移 ,值得注意的是,这里的单个cout一直恒定为1,多个的话,可以使用加法的组合定理。
代码:
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1e5+10;
vector<int> list[maxn];
int indegree[maxn];
queue<int>q;
ll a[maxn];
ll b[maxn];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
while(!q.empty())
q.pop();
for(int i=0;i<=n;i++)
list[i].clear();
met(indegree,0);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i],&b[i]);
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
list[u].push_back(v);
indegree[v]++;
}
for(int i=1;i<=n;i++)
{
if(indegree[i]==0)
q.push(i);
}
ll ans=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<list[u].size();i++)
{
int v=list[u][i];
ans=(ans+(a[u]*b[v])%mod)%mod;
//printf("%lld\n",ans);
a[v]=(a[v]+a[u])%mod;
indegree[v]--;
if(indegree[v]==0)
{
q.push(v);
}
}
}
printf("%lld\n",ans);
}
}