zoukankan      html  css  js  c++  java
  • COGS396. [网络流24题]魔术球问题(简化版

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

    ´数据输入: 
    文件第1 行有 1个正整数n,表示柱子数。 
    ´结果输出: 
    文件的第一行是球数。

    数据规模

    n<=60  保证答案小于1600

    输入文件示例

    4

    输出文件示例

    11

    方案如下

    1 8 
    2 7 9 
    3 6 10 
    4 5 11

    每一行表示一个柱子上的球

    网络流 最小路径覆盖

    从1到1600枚举放的球数量。

    将表示每个球的点拆分出入点和

    从源点S到每个球入点连边,每个球出点到汇点连边,能放在一起的球之间连边(编号小的入点到编号大的出点)。

    球数i-最大流答案m<=柱子数n时,可行。

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 #include<queue>
     9 using namespace std;
    10 const int INF=1e9;
    11 const int mxn=3510;
    12 int read(){
    13     int x=0,f=1;char ch=getchar();
    14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    16     return x*f;
    17 }
    18 struct edge{
    19     int v,nxt,f;
    20 }e[mxn*50];
    21 int hd[mxn],mct=1;
    22 void add_edge(int u,int v,int c){
    23     e[++mct].v=v;e[mct].nxt=hd[u];e[mct].f=c;hd[u]=mct;return;
    24 }
    25 void insert(int u,int v,int c){
    26     add_edge(u,v,c);add_edge(v,u,0);return;
    27 }
    28 int n,m,S,T;
    29 int d[mxn];
    30 bool BFS(){
    31     memset(d,0,sizeof d);
    32     queue<int>q;
    33     q.push(S);
    34     d[S]=1;
    35     while(!q.empty()){
    36         int u=q.front();q.pop();
    37         for(int i=hd[u];i;i=e[i].nxt){
    38             int v=e[i].v;
    39             if(e[i].f && !d[v]){
    40                 d[v]=d[u]+1;
    41                 q.push(v);
    42             }
    43         }
    44     }
    45     return d[T];
    46 }
    47 int DFS(int u,int lim){
    48     if(u==T)return lim;
    49     int tmp,f=0;
    50     for(int i=hd[u];i;i=e[i].nxt){
    51         int v=e[i].v;
    52         if(d[v]==d[u]+1 && e[i].f){
    53             tmp=DFS(v,min(lim,e[i].f));
    54             e[i].f-=tmp;
    55             e[i^1].f+=tmp;
    56             f+=tmp;
    57             lim-=tmp;
    58             if(!lim)return f;
    59         }
    60     }
    61     d[u]=0;
    62     return f;
    63 }
    64 int Dinic(){
    65     int res=0;
    66     while(BFS())res+=DFS(S,INF);
    67     return res;
    68 }
    69 int main(){
    70     freopen("balla.in","r",stdin);
    71     freopen("balla.out","w",stdout);
    72     int i,j;
    73     n=read();m=0;
    74     S=0,T=3201;
    75     for(i=1;i<=1600;i++){
    76         insert(S,i*2-1,1);
    77         insert(i*2,T,1);
    78         for(j=1;j<i;j++){
    79             int t=sqrt(j+i);
    80             if(t*t==j+i){
    81                 insert(j*2-1,i*2,1);
    82             }
    83         }
    84         //
    85         m+=Dinic();
    86         if(i-m>n)break;
    87     }
    88     printf("%d
    ",i-1);
    89     return 0;
    90 }
  • 相关阅读:
    Java 判断日期的方法
    HTTP Session例子
    Unity3D性能优化
    TCP学习之二:客户端与服务端的连接
    TCP学习之一:TCP网络编程概念
    TCP学习之三:客户端、服务端同步传输字符串
    TCP学习之四:传输协议
    Lua与.net的CLR相互调用
    HTC vive开发:关于手柄按键
    JavaSESocket编程之简易聊天系统
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6240225.html
Copyright © 2011-2022 走看看