zoukankan      html  css  js  c++  java
  • 【Cf #290 C】Fox And Dinner(最大流)

    如果要相邻两个数(a[i] >= 2)相加为质数,显然它们的奇偶性不同,也就是说一个圆桌(环)必须是偶环。

    也就是答案的若干个环组成了一张二分图,其中以奇偶分色。

    考虑每个点的度数一定为2,用最大流解决:

    1. 让源点向所有的奇数点连流量为2的边。
    2. 让所有的偶数点向汇点连流量为2的边。
    3. 当且仅当一组奇数和偶数相加为质数时,连一条流量为1的边。

    可以证明,如果最大流小于n,那就不存在解,否则一定存在若干个边数大于2的偶环,使得所有点只出现在一个环里,最后Dfs找出环即可。

    $ igodot $ 技巧&套路:

    • 根据奇偶性或网格图黑白染色,想到建立二分图。
    • 最大流的模型。
      1 #include <cstdio>
      2 #include <vector>
      3 #include <cstring>
      4 #include <algorithm>
      5 
      6 const int N = 305, M = 100005;
      7 
      8 int n, s, t, tot, a[N], vis[N], lc[N], rc[N], ln, rn;
      9 int ntp[20005];
     10 std::vector<int> an[N];
     11 
     12 void Init() {
     13     ntp[1] = 1;
     14     for (int i = 2; i <= 20000; ++i) if (!ntp[i]) {
     15         for (int j = i * i; j <= 20000; j += i) {
     16             ntp[j] = 1;
     17         }
     18     }
     19 }
     20 
     21 namespace GR {
     22     int yun = 1, cur[N], las[N], to[M << 1], pre[M << 1], fl[M << 1];
     23     int h[N], gap[N];
     24     inline void Add(int a, int b, int c) {
     25         to[++yun] = b; fl[yun] = c; pre[yun] = las[a]; las[a] = yun;
     26         to[++yun] = a; fl[yun] = 0; pre[yun] = las[b]; las[b] = yun;
     27     }
     28     int Isap(int x, int flo, int usd = 0) {
     29         if (x == t) return flo;
     30         for (int i = cur[x]; i; i = pre[i]) if (fl[i] > 0 && h[to[i]] + 1 == h[x]) {
     31             int f = Isap(to[i], std::min(flo, fl[i]));
     32             usd += f; fl[i] -= f; fl[i ^ 1] += f;
     33             if (fl[i] > 0) cur[x] = i;
     34             if (usd == flo) return flo;
     35         }
     36         if (gap[h[x]] == 1) h[s] = t + 9;
     37         --gap[h[x]]; ++gap[++h[x]];
     38         cur[x] = las[x];
     39         return usd;
     40     }
     41     int Max_flow(int re = 0) {
     42         memset(h, 0, sizeof h);
     43         memset(gap, 0, sizeof gap);
     44         for (; h[s] < t + 9; ) re += Isap(s, 1e9);
     45         return re;
     46     }
     47 }
     48 
     49 void Build() {
     50     s = n + 1; t = n + 2;
     51     for (int i = 1; i <= n; ++i) {
     52         if (a[i] & 1) {
     53             lc[++ln] = i; GR::Add(s, i, 2);
     54         } else {
     55             rc[++rn] = i; GR::Add(i, t, 2);
     56         }
     57     }
     58     for (int i = 1; i <= ln; ++i) {
     59         for (int j = 1; j <= rn; ++j) {
     60             if (!ntp[a[lc[i]] + a[rc[j]]]) {
     61                 GR::Add(lc[i], rc[j], 1);
     62             }
     63         }
     64     }
     65 }
     66 
     67 void Dfs(int gr, int x) {
     68     an[gr].push_back(x);
     69     vis[x] = 1;
     70     for (int i = GR::las[x]; i; i = GR::pre[i]) {
     71         int v = GR::to[i];
     72         if (vis[v] || v == s || v == t) continue;
     73         if (((~i & 1) && GR::fl[i] == 0) || ((i & 1) && GR::fl[i] == 1)) {
     74             Dfs(gr, v);
     75         }
     76     }
     77 }
     78 
     79 int main() {
     80     Init();
     81     scanf("%d", &n);
     82     for (int i = 1; i <= n; ++i) {
     83         scanf("%d", &a[i]);
     84     }
     85     Build();
     86     
     87     int ans = GR::Max_flow();
     88     if (ans != n) {
     89         puts("Impossible"); return 0;
     90     }
     91     for (int i = 1; i <= n; ++i) {
     92         if (!vis[i]) Dfs(++tot, i);
     93     }
     94     printf("%d
    ", tot);
     95     for (int i = 1; i <= tot; ++i) {
     96         printf("%d ", (int)an[i].size());
     97         for (int j = 0; j < (int)an[i].size(); ++j) {
     98             printf("%d ", an[i][j]);
     99         }
    100         putchar('
    ');
    101     }
    102     
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    .NET 分页
    SQL将用户表中已存在的数据所有姓名(汉字)转换为拼音首字母
    EXECL文件导入数据库
    Jquery ajax
    Jquery学习
    C#动态调用webservice
    使用VSTS的Git进行版本控制(四)——在Visual Studio中管理分支
    使用VSTS的Git进行版本控制(三)——评审历史记录
    使用VSTS的Git进行版本控制(二)——提交保存工作
    使用VSTS的Git进行版本控制(一)——复制现有仓库
  • 原文地址:https://www.cnblogs.com/Dance-Of-Faith/p/9296340.html
Copyright © 2011-2022 走看看