zoukankan      html  css  js  c++  java
  • codeforces 510E. Fox And Dinner 网络流

    题目链接

    给出n个人, 以及每个人的值, 要求他们坐在一些桌子上面, 每个桌子如果有人坐, 就必须做3个人以上。 并且相邻的两个人的值加起来必须是素数。每个人的值都>=2.

    由大于等于2这个条件, 可以知道素数都是奇数, 那么很明显就需要一奇一偶相邻这样做, 那么一个桌子上必定有偶数个人。 一个奇数旁边有两个偶数, 一个偶数旁边有两个奇数。

    所以可以先判断n是否为偶数, 如果是奇数直接输出不可能。

    然后开始奇偶建边, 源点和奇数建边, 权值为2, 因为一个奇数需要和两个偶数匹配; 偶数和汇点建边, 同理权值也为2。

    然后, 如果一个奇数和一个偶数相加得到的数是素数, 那么奇数向偶数连一条边, 权值为1。

    这样跑一遍网络流, 看结果是否等于n, 如果不相等, 说明不可能。如果可能, dfs一下就可以求出几个桌子, 每个桌子上面几个人了。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define pb(x) push_back(x)
      4 #define ll long long
      5 #define mk(x, y) make_pair(x, y)
      6 #define lson l, m, rt<<1
      7 #define mem(a) memset(a, 0, sizeof(a))
      8 #define rson m+1, r, rt<<1|1
      9 #define mem1(a) memset(a, -1, sizeof(a))
     10 #define mem2(a) memset(a, 0x3f, sizeof(a))
     11 #define rep(i, a, n) for(int i = a; i<n; i++)
     12 #define ull unsigned long long
     13 typedef pair<int, int> pll;
     14 const double PI = acos(-1.0);
     15 const double eps = 1e-8;
     16 const int mod = 1e9+7;
     17 const int inf = 1061109567;
     18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
     19 const int maxn = 2e5;
     20 int prime[20005];
     21 int q[maxn*2], head[maxn*2], dis[maxn/10], s, t, a[205], num, vis[205];
     22 struct node
     23 {
     24     int to, nextt, c;
     25     node(){}
     26     node(int to, int nextt, int c):to(to), nextt(nextt), c(c){}
     27 }e[maxn*2];
     28 void init() {
     29     num = 0;
     30     mem1(head);
     31 }
     32 void pre() {
     33     for(int i = 2; i<=20000; i++) {
     34         if(!prime[i])
     35             for(int j = i*i; j<=20000; j+=i) {
     36                 prime[j] = 1;
     37             }
     38     }
     39 }
     40 void add(int u, int v, int c) {
     41     e[num] = node(v, head[u], c); head[u] = num++;
     42     e[num] = node(u, head[v], 0); head[v] = num++;
     43 }
     44 int bfs() {
     45     mem(dis);
     46     dis[s] = 1;
     47     int st = 0, ed = 0;
     48     q[ed++] = s;
     49     while(st<ed) {
     50         int u = q[st++];
     51         for(int i = head[u]; ~i; i = e[i].nextt) {
     52             int v = e[i].to;
     53             if(!dis[v]&&e[i].c) {
     54                 dis[v] = dis[u]+1;
     55                 if(v == t)
     56                     return 1;
     57                 q[ed++] = v;
     58             }
     59         }
     60     }
     61     return 0;
     62 }
     63 int dfs(int u, int limit) {
     64     if(u == t) {
     65         return limit;
     66     }
     67     int cost = 0;
     68     for(int i = head[u]; ~i; i = e[i].nextt) {
     69         int v = e[i].to;
     70         if(e[i].c&&dis[v] == dis[u]+1) {
     71             int tmp = dfs(v, min(limit-cost, e[i].c));
     72             if(tmp>0) {
     73                 e[i].c -= tmp;
     74                 e[i^1].c += tmp;
     75                 cost += tmp;
     76                 if(cost == limit)
     77                     break;
     78             } else {
     79                 dis[v] = -1;
     80             }
     81         }
     82     }
     83     return cost;
     84 }
     85 int dinic() {
     86     int ans = 0;
     87     while(bfs()) {
     88         ans += dfs(s, inf);
     89     }
     90     return ans;
     91 }
     92 vector <int> ve[205];
     93 void dfs1(int u, int pos) {
     94     ve[pos].pb(u);
     95     vis[u] = 1;
     96     for(int i = head[u]; ~i; i = e[i].nextt) {
     97         int v = e[i].to;
     98         if(vis[v])
     99             continue;
    100         if(v == t|| v == s)
    101             continue;
    102         if(i%2==0&&!e[i].c) {
    103             dfs1(v, pos);
    104         }
    105         if(i%2==1&&!e[i^1].c)
    106             dfs1(v, pos);
    107     }
    108 }
    109 int main()
    110 {
    111     int n;
    112     cin>>n;
    113     init();
    114     pre();
    115     for(int i = 0; i<n; i++) {
    116         scanf("%d", &a[i]);
    117     }
    118     if(n&1) {
    119         cout<<"Impossible"<<endl;
    120         return 0;
    121     }
    122     s = n+1, t = n+2;
    123     for(int i = 0; i<n; i++) {
    124         if(a[i]&1) {
    125             add(s, i, 2);
    126         } else {
    127             add(i, t, 2);
    128         }
    129     }
    130     for(int i = 0; i<n; i++) {
    131         for(int j = i+1; j<n; j++) {
    132             if((a[i]&1) != (a[j]&1)) {
    133                 if(!prime[a[i]+a[j]]) {
    134                     if(a[i]&1)
    135                         add(i, j, 1);
    136                     else
    137                         add(j, i, 1);
    138                 }
    139             }
    140         }
    141     }
    142     int ans = dinic();
    143     if(ans != n) {
    144         cout<<"Impossible"<<endl;
    145         return 0;
    146     }
    147     int cnt = 0;
    148     for(int i = 0; i<n; i++) {
    149         if(!vis[i]) {
    150             dfs1(i, cnt++);
    151         }
    152     }
    153     cout<<cnt<<endl;
    154     for(int i = 0; i<cnt; i++) {
    155         cout<<ve[i].size()<<" ";
    156         for(int j = 0; j<ve[i].size(); j++) {
    157             cout<<ve[i][j]+1<<" ";
    158         }
    159         cout<<endl;
    160     }
    161     return 0;
    162 }
  • 相关阅读:
    安装centos虚拟机
    关于区别广播域与冲突域
    网络七层架构
    怎么有效避免黑客使用跳板软件进行攻击窃取信息数据
    C语言猜数字游戏
    页置换算法FIFO、LRU、OPT
    Samza的ApplicationMaster
    Samza文档翻译 : Comparison Introduction
    Samza文档翻译 : Architecture
    Samza文档翻译 : Concepts
  • 原文地址:https://www.cnblogs.com/yohaha/p/5042116.html
Copyright © 2011-2022 走看看