bzoj4562

直接记忆化搜(不记忆化不知道行不行)注意判断单独一个点。

#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
const int maxn=100000+10;
const int maxm=200000+10;
struct hh
{
  int v,next;
}e[maxm];
int n,m,point,ans;
int head[maxn],rd[maxn],cd[maxn],vis[maxn],mem[maxn];
template <class T> void read(T&x)
{
  x=0;char c=getchar();int f=0;
  while(c<'0'||c>'9'){f|=(c=='-');c=getchar();}
  while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^=48),c=getchar();
  x=f?-x:x;
}
void add(int u,int v)
{
  e[++point].v=v;e[point].next=head[u];head[u]=point;
  rd[v]++;cd[u]++;
}
int dfs(int x)
{
  if(!cd[x])
  {
      if(!rd[x])return 0;
    return 1;
  }
  if(mem[x])return mem[x];
  for(int i=head[x];i!=-1;i=e[i].next)
  {
    int v=e[i].v;
    if(vis[v])continue;
    vis[v]=1;
    int k=dfs(v);
    mem[x]+=k;
    vis[v]=0;
  }
  return mem[x];
}
int main()
{
  memset(head,-1,sizeof(head));
  read(n);read(m);
  int u,v;
  for(register int i=1;i<=m;i++)
  {
      read(u);read(v);
      add(u,v);
  }
  for(int i=1;i<=n;i++)
  {
      if(!rd[i])ans+=dfs(i);
  }
  printf("%d",ans);
  return 0;
}
View Code
原文地址:https://www.cnblogs.com/new-hand/p/7740698.html