P4017 최대 먹이사슬 계수(간단한 나무 dp)

14299 단어 acm 더위 훈련dp
P4017 최대 먹이사슬 개수
데이터에 고리가 존재하지 않기 때문에 반드시 먹이사슬의 시작점을 찾을 수 있다. 그러면 먹이사슬의 시작점을 기억화하여 검색한 다음에 끝점까지 1로 되돌아갈 수 있다. 이는 먹이사슬이 있다는 것을 설명하고 없어진다. 구체적으로 코드를 보고 이해하자.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define ull unsigned long long
#define se second
#define endl "
"
#define bug cout< #define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0) using namespace std; const int maxn =1e4+10; const int maxm = 1.5e5+50; const double eps = 1e-18; const double inf = 0x3f3f3f3f; const double lnf = 0x3f3f3f3f3f3f3f3f; const int mod = 80112002; const double pi=3.141592653589; vector<int>ve[maxn]; int n,m; ll in[maxn],dp[maxn]; ll ans=0; ll dfs(int u) { if(ve[u].size()==0) { dp[u]=1; return 1; } ll cnt=0; for(int i=0;i<ve[u].size();i++) { int to=ve[u][i]; if(dp[to])cnt=(cnt+dp[to])%mod; else cnt=(cnt+dfs(to))%mod; } return dp[u]=cnt; } int main() { ms(dp,0); ms(in,0); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); ve[v].push_back(u);// in[u]++; } for(int i=1;i<=n;i++) { if(!in[i]) { for(int j=0;j<ve[i].size();j++) { ans=(ans+dfs(ve[i][j]))%mod; } } } printf("%lld
"
,ans); return 0; }

좋은 웹페이지 즐겨찾기