CSU 1804 有向无环图(图上的dp)

a,b 这里写图片描述

count0
ans[u]=ans[v]/a[v]a[u]+a[u]b[v]


代码:

#include <algorithm>
#include <assert.h>
#include <complex>
#include <ctype.h>
#include <functional>
#include <iostream>
#include <limits.h>
#include <locale.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
//#include <unordered_set>
//#include <unordered_map>

#pragma warning(disable:4996)
using namespace std;

#define mp make_pair
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <ldb, ldb> pdd;

int IT_MAX = 1 << 21;
const int MOD = 1000000007;
const int INF = 1034567891;
const ll LL_INF = 1234567890123456789ll;
const db PI = 3.141592653589793238;
const ldb ERR = 1E-12;
const ll mod = 1e9+7 ;
ll qpow(ll a, ll n){
    LL ans=1;
    while(n){
        if(n&1) ans=ans*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return ans;
}
#define mem(x ,y ) memset(x , y , sizeof(x))
/****/

/****/
int n , m ;
ll ans[100005]  ;
int a[100005] , b[100005] ;
int in[100005] ;
vector <int> v[100005] ;
void dfs(int s){
    if(ans[s] != -1) return ;
    ans[s] = 0 ;
    for(int i=0;i<v[s].size() ;i++){
        int e = v[s][i] ;
        ///cout << s << " " << e << endl ;
        dfs(e) ;
        ans[s] += (a[e]!=0?ans[e]*qpow(a[e],mod-2)%mod:0) * (ll)a[s]%mod + (ll)a[s] * b[e] % mod;
        ans[s] %= mod ;
    }
}
int main() {
    while( cin >> n >> m ){
        mem(in , 0) ;
        mem(ans , -1) ;
        for(int i=1;i<=n;i++) v[i].clear() ;
        for(int i=1;i<=n;i++){
            scanf("%d%d" , a+i , b+i) ;
        }
        for(int i=0;i<m;i++){
            int ta ,tb ; scanf("%d%d" , &ta,&tb) ;
            v[ta].push_back(tb) ; in[tb] ++ ;
        }
        for(int i=1;i<=n;i++)if(in[i] == 0){
            dfs(i) ;
        }
        ll tmp = 0 ;
        for(int i=1;i<=n;i++){
            //cout <<i <<" "<< ans[i] << endl ;
            tmp += ans[i] ;
            tmp %= mod ;
        }
        cout << tmp << endl ;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值