bzoj3661
网络流/贪心
网络流做法是对于每一列,如果一个兔子下一天继续可以存在,那么连一条容量为1的边,然后设立一个中转站,来控制可以换的数量,容量限制l。时限100s,能跑过去我的太慢了,一个点100s
正解是贪心。不会证明。每一只兔子,我们当然希望能够尽量连续多跑几天,给其他兔子留机会。每次把在的兔子和不在的兔子排序,具体程序,然后看前l个能不能交换。
巨慢无比的网络流
#include<bits/stdc++.h>
using namespace std;
const int N = * , inf = << ;
struct edge {
int nxt, to, f;
} e[N * ];
int n, m, k, l, S1, T, S, cnt = ;
int q[N * + ], d[N * + ], head[N * + ], iter[N * + ];
int a[][], b[][];
#define id(i, j) (i - 1) * m + j
inline void link(int u, int v, int f)
{
e[++cnt].nxt = head[u];
head[u] = cnt;
e[cnt].to = v;
e[cnt].f = f;
}
inline void ins(int u, int v, int f)
{
link(u, v, f);
link(v, u, );
}
bool bfs()
{
int l = , r = ;
q[++r] = ;
memset(d, , sizeof(d));
d[] = ;
while(l <= r)
{
int u = q[l++];
for(int i = head[u]; i; i = e[i].nxt) if(e[i].f && !d[e[i].to])
{
d[e[i].to] = d[u] + ;
if(e[i].to == T) return ;
q[++r] = e[i].to;
}
}
return ;
}
int dfs(int u, int delta)
{
if(u == T)
return delta;
int ret = ;
for(int &i = iter[u]; i && delta; i = e[i].nxt) if(e[i].f && d[e[i].to] == d[u] + )
{
int x = dfs(e[i].to, min(delta, e[i].f));
e[i].f -= x;
e[i ^ ].f += x;
ret += x;
delta -= x;
}
d[u] = ;
return ret;
}
inline int dinic()
{
int ret = ;
while(bfs())
{
for(int i = ; i <= T; ++i)
iter[i] = head[i];
ret += dfs(, inf);
}
return ret;
}
void build()
{
T = n * m + N * + m * + ;
S1 = n * m + N * + m * + ;
ins(, S1, k);
for(int i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) if(a[i][j])
{
ins(id(i, j), id(i, j) + N, );
b[i][j] = cnt - ;
}
for(int i = ; i <= n; ++i)
{
if(a[i][])
ins(S1, id(i, ), );
if(a[i][m])
ins(id(i, m) + N, T, );
}
for(int j = ; j <= m; ++j)
ins(n * m + N * + j, n * m + N * + j + m, l);
for(int i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) if(a[i][j])
{
if(j < m)
if(a[i][j + ])
ins(id(i, j) + N, id(i, j + ), );
if(j < m)
ins(id(i, j) + N, n * m + N * + j + , );
if(j > )
ins(n * m + N * + j + m, id(i, j), );
}
}
int main()
{
// freopen("input.txt", "r", stdin);
scanf("%d%d%d%d", &n, &m, &k, &l);
for(int i = ; i <= n; ++i)
{
char s[]; scanf("%s", s + );
for(int j = ; j <= m; ++j)
a[i][j] = s[j] - '';
}
build();
int ans = dinic();
if(ans < k)
{
puts("-1");
return ;
}
for(int j = ; j <= m; ++j)
{
for(int i = ; i <= n; ++i)
if(b[i][j])
if(e[b[i][j]].f == )
printf("%d ", i);
puts("");
}
// fclose(stdin);
return ;
}
贪心
#include<bits/stdc++.h>
using namespace std;
const int N = * , inf = << ;
int n, m, k, l;
typedef pair<int, int> PII;
int pos[][], a[][], mark[];
PII b[][], c[][];
bool cp1(PII x, PII y)
{
return x.first < y.first;
}
bool cp2(PII x, PII y)
{
return x.first > y.first;
}
int main()
{
scanf("%d%d%d%d", &n, &m, &k, &l);
for(int i = ; i <= n; ++i)
{
char s[]; scanf("%s", s + );
for(int j = ; j <= m; ++j)
a[i][j] = s[j] - '';
}
for(int j = ; j <= m; ++j)
for(int i = ; i <= n; ++i) if(a[i][j])
{
int Pos = j;
b[j][i] = c[j][i] = make_pair(, i);
while(a[i][Pos + ])
{
++Pos;
++b[j][i].first;
++c[j][i].first;
}
}
sort(b[] + , b[] + n + , cp2);
for(int i = ; i <= k; ++i)
if(b[][i].first > )
pos[][++pos[][]] = b[][i].second;
if(pos[][] < k)
{
puts("-1");
return ;
}
sort(pos[] + , pos[] + k + );
for(int i = ; i <= k; ++i)
printf("%d ", pos[][i]);
puts("");
for(int j = ; j <= m; ++j)
{
memset(mark, , sizeof(mark));
for(int i = ; i <= k; ++i)
mark[pos[j - ][i]] = ;
for(int i = ; i <= n; ++i)
if(mark[i])
c[j][i].first = -;
else
b[j][i].first = inf;
sort(b[j] + , b[j] + n + , cp1);
sort(c[j] + , c[j] + n + , cp2);
for(int i = ; i <= l; ++i)
if(b[j][i].first < c[j][i].first)
pos[j][i] = c[j][i].second;
else
pos[j][i] = b[j][i].second;
for(int i = l + ; i <= k; ++i)
pos[j][i] = b[j][i].second;
sort(pos[j] + , pos[j] + k + );
for(int i = ; i <= k; ++i)
printf("%d ", pos[j][i]);
puts("");
}
return ;
}
bzoj3661的更多相关文章
- 【BZOJ3661】Hungry Rabbit 贪心
[BZOJ3661]Hungry Rabbit Description 可怕的洪水在夏天不期而至,兔子王国遭遇了前所未有的饥荒,它们不得不去外面的森林里寻找食物.为了简化起见,我们假设兔子王国中有n只 ...
随机推荐
- ThinkPHP---thinkphp模型(M)拓展
(1)创建数据对象 数据对象就是父类模型中的$this->data,AR模式的底层数据操作用到了数据对象.模型实例化之前数据对象只是空数组,后来使用了魔术方法__set设置了数据对象的值. 上述 ...
- 洛谷——P2236 [HNOI2002]彩票
P2236 [HNOI2002]彩票 给你$m$个数,从中挑$n$个数,使得这$n$个数的倒数之和恰好等于$\frac{x}{y}$ 常见的剪纸思路: 如果当前的倒数和加上最小可能的倒数和$>$ ...
- 51nod 1050 循环数组最大子段和【动态规划】
N个整数组成的循环序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的连续的子段和的最大值(循环序列是指n个数围成一个圈,因此需要考虑a[n-1],a[n] ...
- 【IDEA】【Git】pull代码始终无法pull到最新的代码或者提示pull no items 【解决方式】
最近pull代码老是提示pull no items,但是本地并不是最新的代码,看了各种博客始终无法解决,最后靠自己的方式解决.下面是解决方法. 方法:1.首先git --> repository ...
- MySQL4
MySQL数据库4 1 管理索引 创建索引帮助 help CREATE INDEX 创建索引 指令 CREATE INDEX 语法格式 CREATE INDEX index_name ON tbl_n ...
- linux tload-显示系统负载状况
推荐:更多linux 性能监测与优化 关注:linux命令大全 tload命令以图形化的方式输出当前系统的平均负载到指定的终端.假设不给予终端机编号,则会在执行tload指令的终端机显示负载情形. 语 ...
- 关于图片预览使用base64在chrome上的性能问题解决方法
在开发后台上传图片的功能时候使用base64预览图片,结果在传入大量图片后导致chrome崩溃,代码如下 var img = new Image(); var render = new FileRea ...
- 基于python、jupyter-notebook 的金融领域用户交易行为分析
说明:本文重在说明交易数据统计.分析方法,所有数据均为生成的数据 时间原因代码未定义成函数 统计指标:1.用户单日交易行为数据 2.按小时为计算单位,统计用户行为数据(旨在求得一天24小时中每个小时的 ...
- 洛谷 2966 2966 [USACO09DEC]牛收费路径Cow Toll Paths
[题意概述] 给出一个图,点有正点权,边有正边权,通过两点的代价为两点间的最短路加上路径通过的点的点权最大值. 有M个询问,每次询问通过两点的代价. [题解] 先把点按照点权从小到大排序,然后按照这个 ...
- https://gitee.com/tomsun28/bootshiro-------需要研究的项目
https://gitee.com/tomsun28/bootshiro-------需要研究的项目