zoukankan      html  css  js  c++  java
  • 【网络流24题】魔术球问题

    Description

    假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球。
    (1)每次只能在某根柱子的最上面放球。
    (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。
    试设计一个算法,计算出在n根柱子上最多能放多少个球。例如,在4 根柱子上最多可 放11个球。
    ´编程任务:
    对于给定的n,计算在 n根柱子上最多能放多少个球。

    Input

    第1 行有 1个正整数n,表示柱子数。

    Output

    第一行是球数。

    Sample Input

    4

    Sample Output

    11

    Hint

    样例方案如下
    1 8
    2 7 9
    3 6 10
    4 5 11
    每一行表示一个柱子上的球
    n<=60 保证答案小于1600

    正解:网络流

    解题报告:一个点最多上面有一个点,下面有一个点,然后我们就可以由此把图构出来,把一个点拆成两个点,分别管上和下,分别连源点与汇点,把与源点和汇点连的边容量定为1,是完全平方数的再连一条边,然后跑出的最大流就是有多少个可以接在上面,然后用当前的点数减去最大流,就是要用的柱子数,然后动态加点,当要用的柱子数超过n时,上一次的点数就是最多能放的球。

     1 #include <iostream>
     2 #include <iomanip>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <cstring>
     7 #include <algorithm>
     8 #include <string>
     9 #define MIN(a,b) a<b?a:b
    10 #define RG register
    11 const int N = 100000;
    12 const int M = 30000;
    13 const int inf = 2147483641;
    14 
    15 using namespace std;
    16 
    17 int gi(){
    18     char ch=getchar();int x=0;
    19     while(ch<'0' || ch>'9') ch=getchar();
    20     while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    21     return x;
    22 }
    23 
    24 struct date{
    25     int from,to,val;
    26 }nn[N];
    27 
    28 int S,T,m=M,head[N],nxt[N],f[N],dis[N],cnt=1;
    29 
    30 void link(int l,int r){
    31     nn[++cnt]=(date){l,r,1},nxt[cnt]=head[l],head[l]=cnt;
    32     nn[++cnt]=(date){r,l,0},nxt[cnt]=head[r],head[r]=cnt;
    33     return;
    34 }
    35 
    36 int bfs(){
    37     for (RG int i=S; i<=T; ++i) dis[i]=0;
    38     f[1]=0,dis[0]=1;
    39     int l=0,r=1;
    40     while(l<r){
    41         ++l;
    42         for (RG int i=head[f[l]]; i; i=nxt[i])
    43             if (nn[i].val && dis[nn[i].to]==0)
    44                 dis[nn[i].to]=dis[f[l]]+1,
    45                     f[++r]=nn[i].to;
    46         if (dis[T]) return 1;
    47     }
    48     return 0;
    49 }
    50 
    51 int dinic(int xh,int sum){
    52     int s=0;
    53     if (xh==T) return sum;
    54     for (RG int i=head[xh]; i; i=nxt[i])
    55         if (nn[i].val && dis[nn[i].to]==dis[xh]+1){
    56             int tmp=dinic(nn[i].to,MIN(sum,nn[i].val));
    57             sum-=tmp,s+=tmp,nn[i].val-=tmp,nn[i^1].val+=tmp;
    58             if (sum==0) break;
    59         }
    60     if (s==0) dis[xh]=-1;
    61     return s;
    62 }
    63 
    64 int main(){
    65     freopen("magic.in","r",stdin);
    66     freopen("magic.out","w",stdout);
    67     RG int n=gi(),ans=0,xh=0;T=2*M;
    68     for (;;){
    69         ++ans,++xh;
    70         for (RG int i=1; i<xh; ++i)
    71             if ((ceil)(sqrt(i+xh))==(floor)(sqrt(i+xh)))
    72                 link(i,xh+m);
    73         link(S,xh),link(xh+m,T);
    74         while(bfs()) ans-=dinic(S,inf);
    75         if (ans>n) break;
    76     }
    77     printf("%d",xh-1);
    78     return 0;
    79 }
  • 相关阅读:
    python2代码改成python3踩过的坑
    Mac下为什么有的文件名后带一个* 星号?
    Mac 的 Vim 中 delete 键失效的原因和解决方案(转)
    使用pandas处理大型CSV文件(转)
    Java基础——02
    javaee相关基础
    Cookie&Session笔记
    EL&JSTL笔记------jsp
    JavaWeb基础
    Java基础——01
  • 原文地址:https://www.cnblogs.com/cjk2001/p/6431863.html
Copyright © 2011-2022 走看看