LiberOJ 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 551≤n≤55

题目链接:https://loj.ac/problem/6003

题意:中文题目,意思明显。

思路:贪心或者点不重复的最小路径覆盖。现在讲一下我的艰难的ac历程,好吧,其实还是蛮简单的。我首先暴力二分ans,然后求最小路径覆盖是否为n,发现TLE,此时我发现了一个问题,那就是n很小,于是我就把每个n的ans打了个表出来,然后直接跑匹配求最短路,AC了。尽管AC了,然后我发现了,这其实是一个贪心题。按照如下的顺序放球:

1 3 6 10 15....

2 7 9 16 20....

4 5 11 14 22....

8 7 23....

12 13....

....

现在想一下,其实不用打表,直接用匹配跑最短路。将答案从1依次递增,然后每次跑匹配,但是每次跑的时候不需要初始化,也不要从1开始,直接从i开始,因为前面的已经跑过了,并且没有新增加前面的点出度的边,所以可以直接从i开始。最后当最短路径大于n是退出循环就可以了。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int maxn=1e6+100,maxm=1e5+1000,inf=0x3f3f3f3f,mod=1e9+7;
const ll INF=1e18+7;
vector<ll>G[maxn];
bool used[maxn];
int cx[maxn],cy[maxn];
bool vis[maxn];
int res=0;
bool dfs(int u)
{
    for(int i=0; i<G[u].size(); i++)
    {
        int v=G[u][i];
        if(used[v]) continue;
        used[v]=true;
        if(cy[v]<0||dfs(cy[v]))
        {
            cx[u]=v,cy[v]=u;
            return true;
        }
    }
    return false;
}
int solve(int n)
{
    res+=dfs(n);
    return res;
}
int main()
{
    int n;
    scanf("%d",&n);
    int ans=1;
    memset(cx,-1,sizeof(cx));
    memset(cy,-1,sizeof(cy));
    for(int i=1; i<=2000000; i++)
    {
        int x=(int)(sqrt(i+1));
        while(x*x-i<i)
        {
            if(x*x-i>=1) G[i].push_back(x*x-i);
            x++;
        }
        if(i-solve(i)>n) break;
        ans=i;
    }
    memset(vis,false,sizeof(vis));
    printf("%d\n",ans);
    for(int i=ans; i>=1; i--)
    {
        if(vis[i]) continue;
        printf("%d",i);
        for(int j=i; cx[j]!=-1; j=cx[j],vis[j]=true)
            printf(" %d",cx[j]);
        printf("\n");
    }
}

点不重复最短路径覆盖

时间: 2024-10-08 19:35:12

LiberOJ 6003. 「网络流 24 题」魔术球 贪心或者最小路径覆盖的相关文章

[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,? 的球. 每次只能在某根柱子的最上面放球. 在同一根柱子中,任何 2 22 个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在

「网络流24题」魔术球问题

传送门:>Here< 题意:有N根柱子,并且有连续编号的小球依次放入.要求后来的小球只能放在某根柱子最上面的小球上面,并且必须满足这两个小球的编号之和为完全平方数.求最多能放几个小球? 思路分析 真是好题~ 由于N的范围不到60,所以我们可以采用非常暴力的做法. 把问题反过来考虑,如果有N个球,最少用几个柱子?考虑DAG的最小路径覆盖——将能够放在一起的(即和为完全平方数)的小球之间连有向边(小的连到大的),这样的一张图的最小路径覆盖也就是需要的最少的柱子.因此问题就转化为了最小路径覆盖问题—

LiberOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题

#6013. 「网络流 24 题」负载平衡 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 G 公司有 n nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n nn 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入格式 文件的第 1 11 行中有 1 11 个正整数 n nn,表示有 n nn 个仓库.第 2 22 行中有 n nn 个

LiberOJ #6000. 「网络流 24 题」搭配飞行员 最大匹配

#6000. 「网络流 24 题」搭配飞行员 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多. 因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行. 输入格式 第一

LiberOJ #6002. 「网络流 24 题」最小路径覆盖

#6002. 「网络流 24 题」最小路径覆盖 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 给定有向图 G=(V,E) G = (V, E)G=(V,E).设 P PP 是 G GG 的一个简单路(顶点不相交)的集合.如果 V VV 中每个顶点恰好在 P PP 的一条路上,则称 P PP 是 G GG 的一个路径覆盖.P PP 中路径可以从 V VV 的任何一个顶点开始,

LiberOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流

#6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 在一个有 m×n m \times nm×n 个方格的棋盘中,每个方格中有一个正整数. 现要从方格中取数,使任意 2 22 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法. 输入格式 文件第 1 11 行有 2 22 个正整数 m mm 和 n nn,分别表示棋盘的行数和列数

LiberOJ 6004. 「网络流 24 题」圆桌聚餐 网络流版子题

#6004. 「网络流 24 题」圆桌聚餐 内存限制:256 MiB时间限制:5000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 假设有来自 n nn 个不同单位的代表参加一次国际会议.每个单位的代表数分别为 ri r_ir?i??.会议餐厅共有 m mm 张餐桌,每张餐桌可容纳 ci c_ic?i?? 个代表就餐.为了使代表们充分交流,希望从同一个单位来的代表不在同一个餐桌就餐. 试设计一个算法,给出满足要求的

【网络流24题】魔术球问题(最小不相交路径覆盖)

[网络流24题]魔术球问题 2014年3月7日3,5344 Description 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,4的球.(1)每次只能在某根柱子的最上面放球.(2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数.试设计一个算法,计算出在n根柱子上最多能放多少个球.例如,在4 根柱子上最多可放11 个球. 编程任务:对于给定的n,计算在n根柱子上最多能放多少个球. Input Format 文件第1 行有1个正整数n,表示柱子数. Output Fo

【网络流24题】魔术球

LOJ 6003 [网络流24题]魔术球 题面 [题目描述] 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,4,? 的球. 每次只能在某根柱子的最上面放球. 在同一根柱子中,任何 2个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在 n 根柱子上最多能放多少个球. [输入格式] 文件第 1 行有 1 个正整数 n(n <= 50) ,表示柱子数. [输出格式] 第一行是球数.接下来的 n 行,每行是一根柱子上的球的编号. 题解 能放的球数非常少,所以我们