zoukankan      html  css  js  c++  java
  • Prime Independence 【LightOJ

      题意:从N个数中找出一个最大子集,满足这个集合中的任意两个数都不存在质数倍的关系,就匹配1和3就是质数(3)倍,然而1和4就不是质数倍。

      分析:很明显的,从联通集合中求出一个最大独立集,就是独立集问题了,再一分析,不存在“x乘以(质数乘以质数)=y”这样的情况,所以可以看出,这是一个二分图。那么问题变成了求二分图的最大独立集这样的一个问题了。于是,再一分析,我们可以发现这a[i]各不相同,所以我们直接进行存位置,然后链接边,就可以了,这里用HK来跑,用匈牙利的话,是会TLE的。

      当然,这里犯了个大错,就是当求质数的时候,我们可以用x的质数倍存在与否而不是x的质因子除去后的数存在与否,会比较的方便。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cmath>
      4 #include <string>
      5 #include <cstring>
      6 #include <algorithm>
      7 #include <limits>
      8 #include <vector>
      9 #include <stack>
     10 #include <queue>
     11 #include <set>
     12 #include <map>
     13 #include <bitset>
     14 #include <unordered_map>
     15 #include <unordered_set>
     16 #define lowbit(x) ( x&(-x) )
     17 #define pi 3.141592653589793
     18 #define e 2.718281828459045
     19 #define INF 0x3f3f3f3f
     20 #define HalF (l + r)>>1
     21 #define lsn rt<<1
     22 #define rsn rt<<1|1
     23 #define Lson lsn, l, mid
     24 #define Rson rsn, mid+1, r
     25 #define QL Lson, ql, qr
     26 #define QR Rson, ql, qr
     27 #define myself rt, l, r
     28 #define pii pair<int, int>
     29 #define MP(a, b) make_pair(a, b)
     30 using namespace std;
     31 typedef unsigned long long ull;
     32 typedef unsigned int uit;
     33 typedef long long ll;
     34 const int maxN = 4e4 + 7;
     35 vector<int> Prime;
     36 bool vis[500005] = {false};
     37 void Prime_Init()
     38 {
     39     for(int i = 2; i <= 500000; i ++)
     40     {
     41         if(!vis[i])
     42         {
     43             Prime.push_back(i);
     44             for(int j = i * 2; j <= 500000; j += i) vis[j] = true;
     45         }
     46     }
     47 }
     48 int N, a[maxN], pos[500005];
     49 int head[maxN], cnt;
     50 struct Eddge
     51 {
     52     int nex, to;
     53     Eddge(int a=-1, int b=0):nex(a), to(b) {}
     54 } edge[1000006];
     55 inline void addEddge(int u, int v)
     56 {
     57     edge[cnt] = Eddge(head[u], v);
     58     head[u] = cnt ++;
     59 }
     60 inline void _add(int u, int v) { addEddge(u, v); addEddge(v, u); }
     61 void init()
     62 {
     63     cnt = 0;
     64     for(int i = 1; i <= N; i ++) head[i] = -1;
     65 }
     66 namespace HK
     67 {
     68     int mx[maxN], my[maxN];
     69     int dx[maxN], dy[maxN], dis;
     70     bool vis[maxN];
     71     bool searchP()
     72     {
     73         queue<int> Q;
     74         dis = INF;
     75         for(int i = 1; i <= N; i ++) dx[i] = -1;
     76         for(int i = 1; i <= N; i ++) dy[i] = -1;
     77         for(int i = 1; i <= N; i ++)
     78         {
     79             if(mx[i] == -1)
     80             {
     81                 Q.push(i);
     82                 dx[i] = 0;
     83             }
     84         }
     85         while(!Q.empty())
     86         {
     87             int u = Q.front(); Q.pop();
     88             if(dx[u] > dis) break;
     89             for(int i = head[u], v; ~i; i = edge[i].nex)
     90             {
     91                 v = edge[i].to;
     92                 if(dy[v] == -1)
     93                 {
     94                     dy[v] = dx[u] + 1;
     95                     if(my[v] == -1) dis = dy[v];
     96                     else
     97                     {
     98                         dx[my[v]] = dy[v] + 1;
     99                         Q.push(my[v]);
    100                     }
    101                 }
    102             }
    103         }
    104         return dis != INF;
    105     }
    106     bool dfs(int u)
    107     {
    108         for(int i = head[u], v; ~i; i = edge[i].nex)
    109         {
    110             v = edge[i].to;
    111             if(!vis[v] && dy[v] == dx[u] + 1)
    112             {
    113                 vis[v] = 1;
    114                 if(my[v] != -1 && dy[v] == dis) continue;
    115                 if(my[v] == -1 || dfs(my[v]))
    116                 {
    117                     my[v] = u;
    118                     mx[u] = v;
    119                     return 1;
    120                 }
    121             }
    122         }
    123         return 0;
    124     }
    125     int MaxMatch()
    126     {
    127         int res = 0;
    128         for(int i = 1; i <= N; i ++) mx[i] = -1;
    129         for(int i = 1; i <= N; i ++) my[i] = -1;
    130         while(searchP())
    131         {
    132             for(int i = 1; i <= N; i ++) vis[i] = false;
    133             for(int i = 1; i <= N; i ++)
    134             {
    135                 if(mx[i] == -1 && dfs(i)) res ++;
    136             }
    137         }
    138         return res;
    139     }
    140 }
    141 using namespace HK;
    142 int main()
    143 {
    144     Prime_Init();
    145     int T; scanf("%d", &T);
    146     for(int Cas = 1; Cas <= T; Cas ++)
    147     {
    148         scanf("%d", &N);
    149         int maxx = 1;
    150         for(int i = 1; i <= N; i ++) { scanf("%d", &a[i]); maxx = max(maxx, a[i]); }
    151         for(int i = 1; i <= N; i ++) pos[a[i]] = i;
    152         init(); int len = (int)Prime.size();
    153         for(int i = 1, x; i <= N; i ++)
    154         {
    155             x = a[i];
    156             for(int j = 0, v; j < len && Prime[j] * a[i] <= maxx; j ++)
    157             {
    158                 v = pos[Prime[j] * a[i]];
    159                 if(!v) continue;
    160                 _add(i, v);
    161             }
    162         }
    163         printf("Case %d: %d
    ", Cas, N - MaxMatch() / 2);
    164         for(int i = 1; i <= N; i ++) pos[a[i]] = 0;
    165     }
    166     return 0;
    167 }
  • 相关阅读:
    2017年8月21日 星期一 --出埃及记 Exodus 28:43
    2017年8月20日 星期日 --出埃及记 Exodus 28:42
    2017年8月19日 星期六 --出埃及记 Exodus 28:41
    2017年8月18日 星期五 --出埃及记 Exodus 28:40
    2017年8月17日 星期四 --出埃及记 Exodus 28:39
    2017年8月16日 星期三 --出埃及记 Exodus 28:38
    2017年8月15日 星期二 --出埃及记 Exodus 28:37
    2017年8月14日 星期一 --出埃及记 Exodus 28:36
    2017年8月13日 星期日 --出埃及记 Exodus 28:35
    2017年8月12日 星期六 --出埃及记 Exodus 28:34
  • 原文地址:https://www.cnblogs.com/WuliWuliiii/p/14309989.html
Copyright © 2011-2022 走看看