zoukankan      html  css  js  c++  java
  • 【网络流24题】魔术球问题 二分答案+最小路径覆盖

    假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球。 (1)每次只能在某根柱子的最上面放球。 (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。 试设计一个算法,计算出在n根柱子上最多能放多少个球。例如,在4 根柱子上最多可 放11 个球。 编程任务: 对于给定的n,计算在n根柱子上最多能放多少个球。
    由文件input.txt提供输入数据。文件第1 行有1个正整数n(n<=55),表示柱子数。
    程序运行结束时,将n 根柱子上最多能放的球数以及相应的放置方案输出到文件 output.txt中。文件的第一行是球数。接下来的n行,每行是一根柱子上的球的编号。
    Sample Input
    4

    Sample Output

    11 1 8 2 7 9 3 6 10 4 5 11
     
    题解:
    二分最大球数。
    用这几个球来做最小路径覆盖
    能够满足加起来等于平方数的就连边(注意 i<j).
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 using namespace std;
      7 const int N=5005,INF=1999999999;
      8 int gi(){
      9     int str=0;char ch=getchar();
     10     while(ch>'9' || ch<'0')ch=getchar();
     11     while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
     12     return str;
     13 }
     14 int k,head[N],num=1,S=0,T;
     15 struct Lin{
     16     int next,to,dis;
     17 }a[N*10];
     18 void init(int x,int y,int dis){
     19     a[++num].next=head[x];
     20     a[num].to=y;
     21     a[num].dis=dis;
     22     head[x]=num;
     23     a[++num].next=head[y];
     24     a[num].to=x;
     25     a[num].dis=0;
     26     head[y]=num;
     27 }
     28 bool pd(int x,int y){
     29     int tmp=sqrt(x+y);
     30     if(tmp*tmp==x+y)return true;
     31     return false;
     32 }
     33 int q[N],dep[N];
     34 bool bfs()
     35 {
     36     memset(dep,0,sizeof(dep));
     37     int t=0,sum=1,u,x;
     38     q[1]=S;dep[S]=1;
     39     while(t!=sum)
     40     {
     41         x=q[++t];
     42         for(int i=head[x];i;i=a[i].next){
     43             u=a[i].to;
     44             if(a[i].dis<=0 || dep[u])continue;
     45             dep[u]=dep[x]+1;q[++sum]=u;
     46         }
     47     }
     48     return dep[T];
     49 }
     50 int dfs(int x,int flow)
     51 {
     52     if(x==T || !flow)return flow;
     53     int u,tmp,tot=0;
     54     for(int i=head[x];i;i=a[i].next){
     55         u=a[i].to;
     56         if(dep[u]!=dep[x]+1 || a[i].dis<=0)continue;
     57         tmp=dfs(u,min(flow,a[i].dis));
     58         a[i].dis-=tmp;a[i^1].dis+=tmp;
     59         tot+=tmp;flow-=tmp;
     60         if(!flow)break;
     61     }
     62     return tot;
     63 }
     64 int maxflow()
     65 {
     66     int tot=0,tmp;
     67     while(bfs()){
     68         tmp=dfs(S,INF);
     69         while(tmp)tot+=tmp,tmp=dfs(S,INF);
     70     }
     71     return tot;
     72 }
     73 void Clear(){
     74     memset(head,0,sizeof(head));
     75     num=1;
     76 }
     77 bool check(int n)
     78 {
     79     T=(n<<1)+1;
     80     for(int i=1;i<=n;i++)init(S,i,1),init(i+n,T,1);
     81     for(int i=1;i<=n;i++)
     82     for(int j=i+1;j<=n;j++){
     83         if(pd(i,j))
     84         init(i,j+n,INF);
     85     }
     86     int tp=n-maxflow();
     87     return tp<=k;
     88 }
     89 bool vis[N];int ans=0;
     90 void putans(int x)
     91 {
     92     printf("%d ",x);
     93     vis[x]=true;
     94     for(int i=head[x];i;i=a[i].next){
     95         if(a[i].dis==INF-1)putans(a[i].to-ans);
     96     }
     97 }
     98 int main()
     99 {
    100     k=gi();int l=k,r=2000,mid;
    101     while(l<=r){
    102         mid=(l+r)>>1;
    103         if(check(mid))ans=mid,l=mid+1;
    104         else r=mid-1;
    105         Clear();
    106     }
    107     check(ans);
    108     printf("%d
    ",ans);
    109     for(int i=1;i<=ans;i++){
    110         if(vis[i])continue;
    111         putans(i); 
    112         printf("
    ");
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    ssh密钥讲解
    Python之paramiko模块
    Python之socket编程进阶版
    linux内socket服务器无法连接windows
    Python之socket编程
    linux(centOS7,mini),python环境的搭建
    Python 之异常处理机制
    pytho常用模块2——random
    Hadoop基础(二):从Hadoop框架讨论大数据生态
    Hadoop基础(一):概论
  • 原文地址:https://www.cnblogs.com/Yuzao/p/6885852.html
Copyright © 2011-2022 走看看