1. 程式人生 > >CF 284E 拓撲排序+母函式

CF 284E 拓撲排序+母函式

題目連結:https://vjudge.net/contest/257979#problem/L

題目思路:首先對於(bi,ci)的限制,建圖,用拓撲排序,先反向建圖,然後t-=d*a[i],d表示深度,反向建圖in為0的d為1,接著對於樣例1,想新增一個2,,3和4也要跟著加進去,然後用拓撲排序,求出新增每個數所需要的總和

 

AC程式碼:有個坑點:t必須用long long

#include <iostream>
#include<bits/stdc++.h>
using namespace std;

#define mod 1000000007
#define maxn 500
long long sum[maxn];
int deep[maxn];
int in1[maxn];
int out1[maxn];
int in2[maxn];
int out2[maxn];
vector<int>maps1[maxn];
vector<int>maps2[maxn];
long long dp[150000];
long long n,m,t;
int cnt=0;

void topo2()
{
    queue<int>q;
    for(int i=1;i<=n;++i)
        if(in2[i]==0)
        {
            q.push(i);
            deep[i]=0;
        }
    int n1,n2;
    while(!q.empty())
    {
        n1=q.front();
        q.pop();
        cnt++;
        t-=deep[n1]*sum[n1];
        for(int i=0;i<maps2[n1].size();++i)
        {
            n2=maps2[n1][i];
            in2[n2]--;
            deep[n2]=max(deep[n2],deep[n1]+1);
            if(in2[n2]==0)
                q.push(n2);
        }
    }
}

void topo1()
{
    queue<int>q;
    int n1,n2;
    for(int i=1;i<=n;++i)
        if(in1[i]==0)
        {
            q.push(i);
        }
    while(!q.empty())
    {
        n1=q.front();
        q.pop();
        for(int i=0;i<maps1[n1].size();++i)
        {
            n2=maps1[n1][i];
            in1[n2]--;
            sum[n2]+=sum[n1];
            if(in1[n2]==0)
            {
                q.push(n2);
            }
        }
    }
}

int main()
{

    scanf("%lld%lld%lld",&n,&m,&t);
    for(int i=1;i<=n;++i)
        scanf("%lld",&sum[i]);
    for(int i=1;i<=m;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        maps1[x].push_back(y);
        in1[y]++;out1[x]++;
        maps2[y].push_back(x);
        in2[x]++;out2[y]++;
    }
    topo2();
    if(t<0||cnt!=n)
        printf("0\n");
    else
    {
        topo1();
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(int i=1;i<=n;++i)
        {
            for(int j=sum[i];j<=t;++j)
            {
                dp[j]=(dp[j]+dp[j-sum[i]])%mod;
            }
        }
        printf("%lld\n",dp[t]);
    }
    return 0;
}