zoukankan      html  css  js  c++  java
  • 【网络流24题】魔术球问题(最小不相交路径覆盖)

    【网络流24题】魔术球问题

    Description

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

    编程任务:
    对于给定的n,计算在n根柱子上最多能放多少个球。

    Input Format

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

    Output Format

    程序运行结束时,将n 根柱子上最多能放的球数以及相应的放置方案输出。文件的第一行是球数。接下来的n行,每行是一根柱子上的球的编号。

    Sample Inpu

     4

    Sample Output

    11
    1 8
    2 7 9
    3 6 10
    4 5 11

    题解:这道题就是小的必须在大的下面,所以保证了DAG的性质。

    如果a,b(a<b)并且a+b是一个平方数。

    那么a-->b连一条边,那么问题是不是转化为,一个DAG最少需要多少条路径(不想交),可以

    完全覆盖,如果超过了n则不行。

    所以维护一下网络流,codevs上没开spj,路径方面处理一下。

      1 #include<cstring>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<cstdio>
      5 #include<iostream>
      6 #include<queue>
      7 
      8 #define N 10007
      9 #define M 200007
     10 #define INF 1000000007
     11 using namespace std;
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
     16     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 
     20 int n,S,T,ans,s;
     21 int cnt=1,head[N],rea[M],val[M],next[M];
     22 int dis[N],to[N],flag[N];
     23 
     24 void add(int u,int v,int fee)
     25 {
     26     next[++cnt]=head[u];
     27     head[u]=cnt;
     28     rea[cnt]=v;
     29     val[cnt]=fee;
     30 }
     31 bool bfs()
     32 {
     33     for (int i=1;i<=T;i++)dis[i]=0;
     34     dis[S]=1;queue<int>q;q.push(S);
     35     while(!q.empty())
     36     {
     37         int u=q.front();q.pop();
     38         for (int i=head[u];i!=-1;i=next[i])
     39         {
     40             int v=rea[i],fee=val[i];
     41             if (!dis[v]&&fee>0)
     42             {
     43                 dis[v]=dis[u]+1;
     44                 if (v==T) return 1;
     45                 q.push(v);
     46             }
     47         }
     48     }
     49     return 0;
     50 }
     51 int dfs(int u,int MF)
     52 {
     53     int res=0;
     54     if (u==T||MF==0) return MF;
     55     for (int i=head[u];i!=-1;i=next[i])
     56     {
     57         int v=rea[i],fee=val[i];
     58         if (dis[v]!=dis[u]+1) continue;
     59         int x=dfs(v,min(MF,fee));
     60         if (x)
     61         {
     62             val[i]-=x,val[i^1]+=x;
     63             MF-=x,res+=x;
     64             if (MF==0) return res;
     65         }
     66     }
     67     if (!res) dis[u]=0;
     68     return res;
     69 }
     70 void Dinic()
     71 {
     72     int res=0;
     73     while(bfs())
     74     {
     75         int x=dfs(S,INF);
     76         while(x)
     77         {
     78             res+=x;
     79             x=dfs(S,INF);
     80         }
     81     }
     82     ans-=res;
     83 }
     84 int main()
     85 {
     86     memset(head,-1,sizeof(head));
     87     n=read();
     88     S=0,T=10001;
     89     while(true)
     90     {
     91         ans++,s++;
     92         for (int i=1;i<s;i++)
     93             if (sqrt(i+s)==(int)(sqrt(i+s))) add(i,s+5000,1),add(s+5000,i,0);
     94         add(S,s,1),add(s,S,0),add(s+5000,T,1),add(T,s+5000,0);
     95         Dinic();
     96         if (ans>n) break;    
     97     }
     98     printf("%d
    ",s-1);
     99     for (int i=1;i<s;i++)
    100         for (int j=head[i];j!=-1;j=next[j])
    101         {
    102             int v=rea[j],fee=val[j];
    103             if (!fee) {to[i]=v-5000;break;}
    104         }
    105     for (int i=1;i<s;i++)
    106     {
    107         if (flag[i]) continue;
    108         int t=i;
    109         while(t!=-5000)
    110         {
    111             flag[t]=1;
    112             printf("%d ",t);
    113             t=to[t];
    114         }
    115         printf("
    ");
    116     }//十分巧妙的构思,转化问题十分优秀。 
    117 }
  • 相关阅读:
    MyBatis中#{}和${}的区别
    springBoot 配置详解
    模板方法模式
    记录一次linux挂载数据盘
    缓存击穿,缓存穿透,缓存雪崩
    Echart折线值相加问题
    mybatis plus主键生成策略
    BigDecimal精度损失
    cent0s6安装nginx小程序https
    Centos6 java运行环境部署
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7922616.html
Copyright © 2011-2022 走看看