题解 P2835 【刻录光盘】
本题一开始我想用并查集,但普通的并查集是双向的,但本题是单向,用Floyd,在下不才,Pascal转c++刚一个星期,把Pascal的基础代入c++,特发一个c++帖,求大家不喜勿喷
#include <bits/stdc++.h>
using namespace std;
int mapk[210][210],f[210]; //mapk表示一个人愿不愿意给另外一个人拷贝,也可以用布尔型,f表示一个人的父亲节点是哪个人
int main()
{
int n,i,j,k,x;
while(cin >> n)
{
memset(mapk,0,sizeof(mapk)); //初始化
for(i=1;i<=n;i++)
while(scanf("%d",&x),x) //读入
mapk[i][x]=1; //表示第i个人愿意给第x个人拷贝
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(mapk[i][k]&&mapk[k][j])
mapk[i][j]=1;//如果第i个人愿意给第k个人,而第k个人又愿意给第j个人,就相当于第i个人愿意给第j个人
for(i=1;i<=n;i++)
f[i]=i; //一开始,每个人的父亲节点就是自己
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(mapk[i][j]) f[j]=f[i]; //如果i愿意给j拷贝,那么i的父亲节点就是j的父亲节点,注意别搞反了!
int s=0;
for(i=1;i<=n;i++)
if(f[i]==i) s++; //最后用循环扫一遍,如果i的父亲节点就是自己本身的话,计数器加一
cout<<s<<endl; //最后输出
}
return 0;
}
大家注意看懂了再抄,不然还是不懂,我也思考了很久滴