CF 284E 拓撲排序+母函式
阿新 • • 發佈:2018-11-17
題目連結: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; }