NEFU 486 魔术球问题 最小路径覆盖

来源:互联网 发布:安恒数据库审计 编辑:程序博客网 时间:2024/06/07 15:38

题目链接 魔术球问题


魔术球问题

Time Limit 1000ms

Memory Limit 65536K

description

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

input

多组数据输入.每组输入1个正整数n,表示柱子数。

output

每组输出n 根柱子上最多能放的球数。

sample_input

4

sample_output

11

hint

source

线性规划与网络流24题
[submit][back][discuss]



最小路径覆盖=顶点数-最大匹配数。。


在残留网络上增加新的节点和边,然后再增广一次即可


#include <cstdlib>#include <cctype>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <iostream>#include <sstream>#include <map>#include <set>#include <queue>#include <stack>#include <fstream>#include <numeric>#include <iomanip>#include <bitset>#include <list>#include <stdexcept>#include <functional>#include <utility>#include <ctime>using namespace std;#define PB push_back#define MP make_pair#define CLR(vis) memset(vis,0,sizeof(vis))#define MST(vis,pos) memset(vis,pos,sizeof(vis))#define MAX3(a,b,c) max(a,max(b,c))#define MAX4(a,b,c,d) max(max(a,b),max(c,d))#define MIN3(a,b,c) min(a,min(b,c))#define MIN4(a,b,c,d) min(min(a,b),min(c,d))#define PI acos(-1.0)#define INF 0x7FFFFFFF#define LINF 1000000000000000000LL#define eps 1e-8typedef long long ll;typedef unsigned long long ull;const int mm=111111;const int mn=10000;struct Dinic{    int node,s,t,edge,ans;    int ver[mm],cap[mm],flow[mm],next[mm];    int head[mn],work[mn],dis[mn],q[mn];    void init(int _node,int _s,int _t)    {       node=_node, s=_s, t=_t;       for(int i=0;i<node;++i)         head[i]=-1;       edge=ans=0;    }     void addedge(int u,int v,int c)     {       ver[edge]=v,cap[edge]=c,flow[edge]=0,next[edge]=head[u],head[u]=edge++;       ver[edge]=u,cap[edge]=0,flow[edge]=0,next[edge]=head[v],head[v]=edge++;     }     bool Dinic_bfs()     {         int i,u,v,l,r=0;         for(i=0;i<node;++i)  dis[i]=-1;         dis[ q[r++]=s ] = 0;         for(l=0;l<r;l++)         {            for(i=head[ u=q[l] ]; ~i ;i=next[i])               if(flow[i]<cap[i] && dis[ v=ver[i] ]<0)               {                 dis[ q[r++]=v ]=dis[u]+1;                 if(v==t) return 1;               }          }          return 0;      }      int Dinic_dfs(int u,int exp)      {          if(u==t) return exp;          for(int &i=work[u],v,temp; ~i ;i=next[i])          {             if(flow[i]<cap[i] && dis[ v=ver[i] ]==dis[u]+1 && ( temp=Dinic_dfs(v,min(exp,cap[i]-flow[i])) )>0)             {               flow[i]+=temp;               flow[i^1]-=temp;               return temp;             }          }          return 0;      }      int Dinic_flow()      {         int res,i;         while(Dinic_bfs())         {           for(i=0;i<node;++i) work[i]=head[i];           while( ( res=Dinic_dfs(s,INF) ) )  ans+=res;         }         return  ans ;     }};bool judge(int a){    int b=sqrt(a);    if(b*b==a)        return true;    else return false;}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        int num=0;        Dinic e;        e.init(2*n+2,0,1);        for(int i=2;i<=2*n+1;i++)        {            if(i%2==0)             e.addedge(e.s,i,1);            else             e.addedge(i,e.t,1);        }        for(int i=2;i<=n;i++)        {            for(int j=1;j<i;j++)            {                if(judge(i+j))                    e.addedge(2*j,2*i+1,1);            }        }        num=n;        int x,y;        while(num-e.Dinic_flow()<=n)        {            num++;            e.head[x=e.node++]=-1;            e.head[y=e.node++]=-1;            e.addedge(e.s,x,1);            e.addedge(y,e.t,1);            for(int i=1;i<num;i++)            {                if(judge(i+num))                    e.addedge(2*i,2*num+1,1);            }        }        cout<<num-1<<endl;    }    return 0;}


0 0