其实这道题把脑洞放大的话就会想到一种骗分的方法:记录每一个描述中出现的人,最后有几个剩下的没有被记录的人就需要几张光盘
代码奉上

#include<iostream> using namespace std; bool book[1000]; int n,s,x; int main() { cin>>n; for(int i=1;i<=n;i++) while (cin>>s!=0) book[s]=true;//输入以0结束,将描述中给出的人标记 for(int i=1;i<=n;i++) if(!book[i]) x++;//如果未被标记,光盘数加1 if(x==0)//如果所有人都可以通过拷贝得到资料那么就只需要一张光盘 cout<<x+1; else cout<<x; return 0; }
当然作为一名程序员仅仅会骗分是不行的
这里用Floyd判联通……

#include<cstdio> #include<iostream> using namespace std; int f[209],n,x,ans=0; bool b[209][209]; void Floyd() { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(b[i][j]||(b[i][k]&&b[k][j]))//Floyd…… { b[i][j]=1; } } int main() { cin>>n; for(int i=1;i<=n;i++) { f[i]=i;//各种初始化 for(int j=1;j<=n;j++) { b[i][j]=0; } } for(int i=1;i<=n;i++) { cin>>x;//输入 for(;x!=0;) { b[i][x]=1; cin>>x; } } Floyd(); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) if(b[i][j]) f[j]=f[i];//找出可以互相拷贝的 } for(int i=1;i<=n;i++) { if(f[i]==i) ans++;//计算光盘数 } cout<<ans; }