zoukankan      html  css  js  c++  java
  • Lightoj1356

    题目链接:https://vjudge.net/problem/LightOJ-1356

    题目大意:

      T个 test case,每个 test case 给出一个 N 个数的集合。请找出一个最大的子集,使得子集中的任何一个数除以子集中的任意的另一个数所得到的数不是质数。

    解题思路:

      先用素数筛找出 1 到 500000 的所有质数。

      在输入一个集合的时候,我们顺便记录下输入的这个数在输入数组中的位置,找出它的所有质因数,记录下质因数的总个数,用一个vector记录下所有 “不同的” 质因数。

      遍历输入数组中的每一个数,对于每个数,遍历其所有 “不同的” 质因数,如果找到这样的一个质因数:该数除以这个质因数能得到输入数组中的另一个数,那么将这两个数连边。

      将由上述的连边操作得到的图中的点分成两类:质因数总个数为奇数的点和质因数总个数为偶数的点(这个划分有点隐晦,我多说两句:其实,对于连边的两个数,二者各自的所有质因数其实就只有一个质数的差别,其中一个数的所有质因数中有这个质数,但另一个数没有,其他的质因数都相同;所以,他们质因数的总个数相差 1,故其中一个为奇数,一个为偶数),这样一来,这个图就变成一个二分图了。而答案其实就是求这个二分图的最大独立集。

      另:用匈牙利算法者,T!用 Hopcroft-Carp者方有可能AC。

    AC代码:

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <vector>
      5 #include <queue>
      6 
      7 using namespace std;
      8 const int inf=0x3f3f3f3f;
      9 
     10 bool prime[500003];
     11 int have[500003],num[40003];
     12 int prims[300003];
     13 
     14 vector<int> G[40003];
     15 int uN;
     16 int l[40003];
     17 int Mx[40003],My[40003];
     18 int dx[40003],dy[40003];
     19 int dis;
     20 bool used[40003];
     21 bool SearchP(){
     22     queue<int>Q;
     23     dis=inf;
     24     memset(dx,-1,sizeof(dx));
     25     memset(dy,-1,sizeof(dy));
     26     for(int i=0;i<uN;i++){
     27         if(Mx[l[i]]==-1){
     28             Q.push(l[i]);
     29             dx[l[i]]=0;
     30         }
     31     }
     32     while(!Q.empty()){
     33         int u=Q.front();
     34         Q.pop();
     35         if(dx[u]>dis)   break;
     36         int sz=G[u].size();
     37         for(int i=0;i<sz;i++){
     38             int v=G[u][i];
     39             if(dy[v]==-1){
     40                 dy[v]=dx[u]+1;
     41                 if(My[v]==-1) dis=dy[v];
     42                 else{
     43                     dx[My[v]]=dy[v]+1;
     44                     Q.push(My[v]);
     45                 }
     46             }
     47         }
     48     }
     49     return dis!=inf;
     50 }
     51 bool DFS(int u){
     52     int sz=G[u].size();
     53     for(int i=0;i<sz;i++){
     54         int v=G[u][i];
     55         if(!used[v]&&dy[v]==dx[u]+1){
     56             used[v]=true;
     57             if(My[v]!=-1&&dy[v]==dis)   continue;
     58             if(My[v]==-1||DFS(My[v])){
     59                 My[v]=u;
     60                 Mx[u]=v;
     61                 return true;
     62             }
     63         }
     64     }
     65     return false;
     66 }
     67 int MaxMatch(){
     68     int res=0;
     69     memset(Mx,-1,sizeof(Mx));
     70     memset(My,-1,sizeof(My));
     71     while(SearchP()){
     72         memset(used,false,sizeof(used));
     73         for(int i=0;i<uN;i++){
     74             if(Mx[l[i]]==-1&&DFS(l[i]))   res++;
     75         }
     76     }
     77     return res;
     78 }
     79 void init(){
     80     memset(prime,true,sizeof(prime));
     81     prime[0]=prime[1]=false;
     82     int cnt=0;
     83     for(int i=2;i<=500000;i++){
     84         if(prime[i]){
     85             prims[cnt++]=i;
     86             for(int j=2*i;j<=500000;j+=i)
     87                 prime[j]=false;
     88         }
     89     }
     90 }
     91 int zhis[40003];
     92 vector<int> zhiyinshu[40003];
     93 int main(){
     94     init();
     95     int T,N;
     96     scanf("%d",&T);
     97     for(int t=1;t<=T;t++){
     98         scanf("%d",&N);
     99         memset(have,0,sizeof(have));
    100         memset(zhis,0,sizeof(zhis));
    101         for(int i=1;i<=N;i++){
    102             G[i].clear();
    103             zhiyinshu[i].clear();
    104             scanf("%d",&num[i]);
    105             have[num[i]]=i;
    106             int tmp=num[i];
    107             for(int j=0;;j++){
    108                 if(prime[tmp]){
    109                     zhiyinshu[i].push_back(tmp);
    110                     zhis[i]++;
    111                     break;
    112                 }
    113                 if(tmp%prims[j]==0){
    114                     tmp/=prims[j];
    115                     zhiyinshu[i].push_back(prims[j]);
    116                     zhis[i]++;
    117                     while(tmp%prims[j]==0){
    118                         tmp/=prims[j];
    119                         zhis[i]++;
    120                     }
    121                 }
    122                 if(tmp<prims[j])    break;
    123             }
    124         }
    125         for(int i=1;i<=N;i++){
    126             for(int j=0;j<zhiyinshu[i].size();j++){
    127                 if(have[num[i]/zhiyinshu[i][j]]){
    128                     int u=have[num[i]/zhiyinshu[i][j]];
    129                     G[i].push_back(u);
    130                     G[u].push_back(i);
    131                 }
    132             }
    133         }
    134 
    135         uN=0;
    136         for(int i=1;i<=N;i++){
    137             if(zhis[i]%2==1){
    138                 l[uN++]=i;
    139             }
    140         }
    141         printf("Case %d: %d
    ",t,N-MaxMatch());
    142     }
    143     return 0;
    144 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    oracle中Blob和Clob类型的区别
    为什么要分库分表
    Enable file editing in Visual Studio's debug mode
    SQL Server Dead Lock Log
    Debug .NET Framework Source
    SQL Server text field里面有换行符的时候copy到excel数据会散乱
    诊断和修复Web测试记录器(Web Test Recorder)问题
    Can't load Microsoft.ReportViewer.ProcessingObjectModel.dll
    'telnet' is not recognized as an internal or external command
    Linq to XML
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7566255.html
Copyright © 2011-2022 走看看