csu 1804(有向无环图)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
const int mod=1e9+7;

/*
	因为是有向的无环图,要找(i,j)之间的路径数,
	肯定是考虑toposort就可以了
	然后就是考虑怎么统计cnt(i,j)*a[i]*b[j]
	如果cnt[i]表示到达i的种类,res[i]表示所有到达i点的cnt[*]*a[*]
	的和,那么最后res[i]*b[i]就是最后的答案
*/

int head[maxn],nxt[maxn],val[maxn];
ll  res[maxn],tot;
int a[maxn],b[maxn],deg[maxn];

void init(){
	tot=0;
	memset(head,-1,sizeof(head));
	memset(res,0,sizeof(val));
	memset(deg,0,sizeof(deg));
}

void add(int u,int v){
	val[tot]=v;
	nxt[tot]=head[u];
	head[u]=tot++;
}
int n,m,u,v;

void solve(){
	queue<int> q;
	
	for(int i=1;i<=n;i++)
		if(!deg[i])q.push(i);
	
	while(!q.empty()){
		u=q.front();q.pop();
		for(int i=head[u];i!=-1;i=nxt[i]){
			v=val[i];
			res[v]=(res[v]+res[u]+a[u])%mod;
			deg[v]--;
			if(!deg[v])q.push(v);
		}
	}
}

int main(){
	while(~scanf("%d%d",&n,&m)){
		init();
		for(int i=1;i<=n;i++)scanf("%d%d",a+i,b+i);
		for(int i=0;i<m;i++){
			scanf("%d%d",&u,&v);
			add(u,v);
			deg[v]++;
		}
		
		solve();

		ll ans=0;
		for(int i=1;i<=n;i++)
			ans=(ans+res[i]*b[i])%mod;
		printf("%lld\n",ans);
	}
	return 0;
}

  

posted @ 2017-04-07 14:16  N维解析几何  阅读(175)  评论(0编辑  收藏  举报