zoukankan      html  css  js  c++  java
  • 魔术球问题

    枚举放的球,先假设新建柱子,拆成两个点,第一个点连S,表示后面还可以放;第二个连T表示放到其他柱子上;再枚举放过的数和它是否组成完全平方数,枚举的数的第一个点向它的第二个点连边,表示这个球可以放到其他球上,容量都为一
    每次跑最大流出来的表示会消掉的柱子个数,如果此时球-消去的比n大则break输出答案

    # include <stdio.h>
    # include <stdlib.h>
    # include <iostream>
    # include <string.h>
    # include <math.h>
    # define ll long long
    # define RG register
    # define IL inline
    # define mem(a, b) memset(a, b, sizeof(a))
    # define Max(a, b) (((a) > (b)) ? (a) : (b))
    # define Min(a, b) (((a) < (b)) ? (a) : (b))
    # define Sqr(a) ((a) * (a))
    using namespace std;
    
    IL int Get(){
        RG char c = '!'; RG int x = 0, z;
        for(; c > '9' || c < '0'; c = getchar()) z = (c == '-') ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
        return x * z;
    }
    
    const int MAXN = 10001, MAXM = 200001, INF = 2147483647;
    int n, m, ft[MAXN], cnt, ans, level[MAXN], Q[MAXM], cur[MAXN], match[MAXN], vis[MAXN];
    struct Edge{
        int to, nt, f;
    } edge[MAXM];
    
    IL void Add(RG int u, RG int v, RG int f){
        edge[cnt] = (Edge){v, ft[u], f}; ft[u] = cnt++;
    }
    
    IL bool Bfs(RG int S, RG int T){
        mem(level, 0);
        RG int head = 0, tail = 0;
        level[S] = 1; Q[0] = S;
        while(head <= tail){
            RG int u = Q[head++];
            for(RG int e = ft[u]; e != -1; e = edge[e].nt){
                RG int v = edge[e].to;
                if(!level[v] && edge[e].f){
                    level[v] = level[u] + 1;
                    Q[++tail] = v;
                }
            }
        }
        return level[T];
    }
    
    IL int Dfs(RG int u, RG int T, RG int maxf){
        if(u == T) return maxf;
        RG int ret = 0;
        for(RG int &e = cur[u]; e != -1; e = edge[e].nt){
            RG int v = edge[e].to;
            if(level[v] == level[u] + 1 && edge[e].f){
                RG int f = Dfs(v, T, Min(maxf - ret, edge[e].f));
                edge[e].f -= f; edge[e ^ 1].f += f;
                ret += f; match[u] = v;
                if(ret == maxf) break;
            }
        }
        if(!ret) level[u] = 0;
        return ret;
    }
    
    int main(){
        mem(ft, -1);
        n = Get();
        RG int S = 0, T = 4000, num = 0;
        while(++num){
            Add(S, num, 1); Add(num, S, 0);
            Add(num + 2000, T, 1); Add(T, num + 2000, 0);
            for(RG int i = 1; i < num; i++)
                if(Sqr((int)sqrt(i + num)) == i + num)
                    Add(i, num + 2000, 1), Add(num + 2000, i, 0);
            while(Bfs(S, T)){
                for(RG int i = S; i <= T; i++)
                    cur[i] = ft[i];
                ans += Dfs(S, T, INF);
            }
            if(num - ans > n){
                printf("%d
    ", num - 1);
                break;
            }
        }
        for(RG int i = 1; i < num; i++)
            if(!vis[i]){
                RG int j = i;
                while(j){
                    if(j != 2000 && j != 4000) j > 2000 ? printf("%d ", j -= 2000) : printf("%d ", j);
                    vis[j] = 1;
                    j = match[j];
                }
                printf("
    ");
            }
        return 0;
    }
  • 相关阅读:
    MD5工具类
    新搭建mysql容易出现问题
    docker自动化部署
    k8s入门案例
    docker单一部署jenkins
    Sentinel 学习-简介
    mysql innerjoin,leftjoin,group by,having
    批量更新 分割list 多线程处理
    redis 3.0+ cluser 集群搭建
    ELK 和 Logstach
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206332.html
Copyright © 2011-2022 走看看