zoukankan      html  css  js  c++  java
  • [最短路-Floyd][并查集]SSL P2344 刻录光盘

    Description

    在PJOI2010夏令营快要结束的时候,很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家,以便大家回去后继续学习。组委会觉得这个主意不错!可是组委会一时没有足够的空光盘,没法保证每个人都能拿到刻录上资料的光盘,又来不及去买了,怎么办呢? 

    组委会把这个难题交给了DYJ,DYJ分析了一下所有营员的地域关系,发现有些营员是一个城市的,其实他们只需要一张就可以了,因为一个人呢拿到光盘以后,其他人可以拿着U盘之类的东西去拷贝啊! 

    可是DYJ调查后发现,有些营员并不是那么合作,他们愿意某一些人到他那儿拷贝资料,当然也可能不愿意让另外一些人到他那儿拷贝资料,这与我们PJOI宣扬的团队合作精神格格不入! 

    现在假设总共有N个营员(2<=N<=200),每个营员的编号为1~N。DJY给每个人发了一张调查表,让每个营员填上自己愿意让哪些人到他那儿拷贝资料。当然,如果A愿意把资料拷贝给B,而B又愿意把资料拷贝给C,则一旦A获得了资料,则B、C也会获得资料。 

    现在请你编写一个程序,根据回收上来的调查表,帮助DZY计算出组委会至少要刻录多少张光盘,才能保证所有营员回去后都能得到夏令营资料?

    Input

    先是一个数N,接下来N行,分别表示各个营员愿意把自己获得的资料拷贝给其他哪些营员。即输入数据的第N+1行表示第i个营员愿意把资料拷贝给那些营员编号,以一个0结束。如果一个营员不愿意拷贝资料给任何人,则相应的行只有1个0,一行中的若干数之间用一个空格隔开。

    Output

    一个正整数,表示最少要刻录的光盘数。

    Sample Input

    5
    2 4 3 0
    4 5 0
    0
    0
    1 0

    Sample Output

    1

    题解

    • 题目其实就是让我们求有多少个联通块
    • 那么其实我们将给出的边定为true
    • 跑一遍Floyd,可以将可以达到的点全部跑出来
    • 然后,将这些边打进并查集
    • 最后求有多少个并查集

    代码

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 int n,ans,f[210],v[210][210],a[210];
     5 void bing(int x,int y)
     6 {
     7     while (x!=f[x]) x=f[x];
     8     f[y]=x;
     9 }
    10 int getfather(int x)
    11 {
    12     while (x!=f[x]) x=f[x];
    13     return x;
    14 }
    15 int main()
    16 {
    17     scanf("%d",&n);
    18     for (int i=1;i<=n;i++) f[i]=i;
    19     for (int i=1;i<=n;i++)
    20     {
    21         int x;
    22         scanf("%d",&x);
    23         while (x!=0)
    24         {
    25             v[i][x]=true;
    26             scanf("%d",&x);
    27         }
    28     }
    29     for (int k=1;k<=n;k++)
    30         for (int i=1;i<=n;i++)
    31             for (int j=1;j<=n;j++)
    32                 v[i][j]=v[i][j]||v[i][k]&&v[k][j];
    33     for (int i=1;i<=n;i++)
    34         for (int j=1;j<=n;j++)
    35             if (v[i][j])
    36                 bing(i,j);
    37     for (int i=1;i<=n;i++) a[getfather(i)]=1;
    38     for (int i=1;i<=n;i++) if (a[i]==1) ans++;
    39     printf("%d",ans);
    40     return 0;
    41 }
  • 相关阅读:
    数据取证任务
    VMware虚拟机重置密码
    pon(无源光纤网络)
    Gpon与Epon的区别
    DNS相关
    牛人博客收集
    值得细细品读的URL资源
    SQL注入
    IPSec方案部署(多业务场景)
    python专题-函数式编程
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8574443.html
Copyright © 2011-2022 走看看