HDU 5506(GT and set)

来源:互联网 发布:淘宝号登不上去 编辑:程序博客网 时间:2024/05/20 00:53

题意:

表示看了很久,然而发现还是没看懂题. 

正解:给你a个集合,让你把他们合并成k个,当两个集合有公共数字时可以合并。

(一直以为是合并后,每个集合至少有两个数字相同- -,这英语也是醉了)


思路:

所以我们应该选择k个覆盖集合尽可能大的数,所以进行k次查找,每次找出没合并集合中最大的一个。

然后再判断是否所有集合都被覆盖了。



#include <iostream>#include <cstdio>#include <vector>#include <queue>#include <cstring>#include <functional>#include <algorithm>#include <memory>using namespace std;int tmax;int a;int vis[305];int n,k,m;int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&k);        tmax = 0;        vector<int>q[305];        for(int i = 0; i <= n; i++)            q[i].clear();        for(int i = 0; i < n; i++)        {            scanf("%d",&m);            memset(vis,0,sizeof(vis));            for(int j = 0; j < m; j++)            {                scanf("%d",&a);                tmax= max(tmax,a);                q[a].push_back(i);               //每个数所占的集合            }        }        int c = 0;        while(c < k)        {            int num = -1;            int position = -1;            for(int j = 0; j <= tmax; j++)            {                int tt = 0;                for(int i = 0; i < q[j].size(); i++)                {                    if(!vis[q[j][i]])                    {                        tt++;                    }                }                if(tt > num)     //找出覆盖最大的J                {                    num = tt;                    position = j;                }            }            for(int i = 0; i < q[position].size(); i++)     //把J覆盖的除去                vis[q[position][i]] = 1;            c++;        }        int flag = 0;        for(int i = 0; i < n; i++)        {            if(!vis[i])            {                flag = 1;                break;            }        }        if(flag )            printf("No\n");        else            printf("Yes\n");    }}



0 0