1.刻录光盘
通过Floyed加并查集。Floyed是在a到c是最短路径经过b的话,那么a到b和b到c也是最短路径。
#include <iostream>
#include <algorithm>
using namespace std;
const int max_n=300;
int fa[max_n];
bool vis[max_n][max_n];
int ans;
void init(int n)
{
for(int i=1;i<=n;i++)
fa[i]=i;
}
int main()
{
int n;
cin >> n;
for(int i=1;i<=n;i++)
{
int t;
cin >> t;
while(t!=0)
{
vis[i][t]=1;
cin >> t;
}
}
init(n);//初始化
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
if(vis[j][k]||(vis[j][i]&&vis[i][k]))//可以理解,前面一段是直接给,后面是j愿意分
vis[j][k]=1;// 享i且i愿意分享给k那么j就是可以分享给k的
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(vis[i][j]==1)//与i在同一集合,将根变成一样
fa[j]=fa[i];
for(int i=1;i<=n;i++)//有几个跟就代表有几个集合,就需要几张光盘
if(fa[i]==i)ans++;
cout << ans;
}