U149505 舞会邀请

题目描述

Smart是一位颇有成就的艺术家,他因油画作品《印象黄昏》闻名于世界。现在,他为了报答帮助他的同行们,准备开一个舞会。
Smart准备邀请n个已经确定的人,可是问题来了:
这n个人每一个人都有一个小花名册,名册里面写着他能够通知到的人的名字。比如说在A的人名单里写了B,那么表示A能够通知到B;但是B的名单里不见得有A,也就是说B不见得能够通知到A。
Smart觉得需要确定自己需要通知到多少个人(人数m),能够实际将所有n个人都通知到。并求出一种方案以确定m的最小值是多少。
注意:自己的名单里面不会有自己的名字。

输入格式

第一行一个数n(1≤n≤200)。接下来n行,第i+1行表示编号为i的人的小花名册名单,名单以0结束。

输出格式

一个整数,即m的值。

思路

显然,我们要求强连通缩点以后,入度为0的点的个数,floyd解决
话说我的数据我写题解不过分吧
code:

#include<iostream>
#include<cmath>
using namespace std;
int n,x,y;
int a[101][101],flag[101];
int main()
{
    
    
 scanf("%d",&n);
 for (int i=1;i<=n;i++)
 {
    
    
  scanf("%d",&y);
  while (y!=0) a[i][y]=1,scanf("%d",&y);
 }
 for (int i=1;i<=n;i++)
 {
    
    
  for (int j=1;j<=n;j++)
  {
    
    
   for (int k=1;k<=n;k++)
   {
    
    
    a[j][k]|=a[j][i]&a[i][k];
   }
  }
 }
 int ans=0;
 for (int i=1;i<=n;i++)
 {
    
    
  if (flag[i]) continue;
  flag[i]=1;
  a[i][i]=1;
  bool o=1;
  for (int j=1;j<=n;j++)
  {
    
    
   if (a[j][i]==1&&a[i][j]==1)
   {
    
    
    flag[j]=1;
   }
   if (a[j][i]&&!a[i][j])
   {
    
    
    o=0;
   }
  }
  ans+=o;
 }
 printf("%d",ans);
 fclose(stdin);
 fclose(stdout);
 return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_49843717/article/details/112981571