zoukankan      html  css  js  c++  java
  • [loj #6003]「网络流 24 题」魔术球 二分图最小路径覆盖,网络流

    #6003. 「网络流 24 题」魔术球

    内存限制:256 MiB时间限制:1000 ms标准输入输出
    题目类型:传统评测方式:Special Judge
    上传者: 匿名

    题目描述

    假设有 n nn 根柱子,现要按下述规则在这 n nn 根柱子中依次放入编号为 1,2,3,4,⋯ 1, 2, 3, 4, cdots1,2,3,4,⋯ 的球。

    1. 每次只能在某根柱子的最上面放球。
    2. 在同一根柱子中,任何 2 22 个相邻球的编号之和为完全平方数。

    试设计一个算法,计算出在 n nn 根柱子上最多能放多少个球。

    输入格式

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

    输出格式

    第一行是球数。接下来的 n nn 行,每行是一根柱子上的球的编号。

    样例

    样例输入

    4

    样例输出

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

    数据范围与提示

    1≤n≤55 1 leq n leq 551n55

    把每个柱子看成一条路径,跑最小路径覆盖。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 struct data {
     9     int to,next,f;
    10 }e[100005];
    11 int head[5005],cnt;
    12 void add(int u,int v,int f){e[cnt].to=v;e[cnt].next=head[u];e[cnt].f=f;head[u]=cnt++;}
    13 int n,m,s,t;
    14 bool vis[5005];
    15 int q[5005],dis[5005];
    16 bool bfs() {
    17     memset(dis,-57,sizeof(dis));
    18     int h=0,tail=1;
    19     q[h]=t;
    20     dis[t]=0;
    21     while(h!=tail) {
    22         int now=q[h++];if(h==5000) h=0;
    23         for(int i=head[now];i>=0;i=e[i].next) {
    24             if(dis[e[i].to]>-100000||!e[i^1].f) continue;
    25             dis[e[i].to]=dis[now]-1;
    26             q[tail++]=e[i].to;if(tail==5000) tail=0;
    27         }    
    28     }
    29     return dis[s]>=-100000;
    30 }
    31 int dfs(int now,int a) {
    32     int f=0,flow=0;
    33     if(now==t) return a;
    34     for(int i=head[now];i>=0;i=e[i].next) {
    35         int to=e[i].to;
    36         if(dis[to]==dis[now]+1&&e[i].f>0) {
    37             f=dfs(to,min(a,e[i].f));
    38             flow+=f;
    39             e[i].f-=f;
    40             e[i^1].f+=f;
    41             a-=f;
    42             if(a==0) break;
    43         }
    44     }
    45     return flow;
    46 }
    47 int num=0;
    48 int ans=0;
    49 int sum=0;
    50 int dinic() {
    51     while(bfs()) {
    52         sum+=dfs(s,2147483647);
    53     }
    54     return num-sum;
    55 }
    56 
    57 bool work() {
    58     num++;
    59     add(s,num,1);add(num,s,0);add(num+2500,t,1);add(t,num+2500,0);
    60     for(int i=1;i<num;i++) {
    61         if(sqrt(i+num)==(int)sqrt(i+num)) add(num,i+2500,1),add(i+2500,num,0);
    62     }
    63     if(dinic()<=n) return 1;
    64     else return 0;
    65 }
    66 void pout(int x) {
    67     vis[x]=1;
    68     printf("%d ",x);
    69     for(int i=head[x+2500];i>=0;i=e[i].next) {
    70         if(e[i].f==1&&!vis[e[i].to]){pout(e[i].to);return;}
    71     }
    72     return;
    73 }
    74 int main() {
    75     memset(head,-1,sizeof(head));
    76     scanf("%d",&n);
    77     s=0,t=5001;
    78     while(work()) ;
    79     num--;
    80     printf("%d
    ",num);
    81     memset(vis,0,sizeof(vis));
    82     vis[s]=vis[t]=1;
    83     for(int i=1;i<=num;i++) {
    84         if(!vis[i]){pout(i);printf("
    ");}
    85     }
    86 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    java 构建一个简单的菜单
    java JSplitPane
    java 使用ActionListener监控
    java 显示单选按钮
    工作 激情
    明天会更好
    记录
    现在
    嘿嘿
    书籍 知识
  • 原文地址:https://www.cnblogs.com/wls001/p/7943664.html
Copyright © 2011-2022 走看看