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只 ...
随机推荐
- BZOJ3124: [Sdoi2013]直径 (树形DP)
题意:给一颗树 第一问求直径 第二问求有多少条边是所有直径都含有的 题解:求直径就不说了 解第二问需要自己摸索出一些性质 任意记录一条直径后 跑这条直径的每一个点 如果以这个点不经过直径能到达最远的 ...
- 考试总结(CE???)
直接开写题解: (由于T1为暴力模拟,不进行整理) T2: 扶苏给了你一棵树,这棵树上长满了幼嫩的新叶,我们约定这棵树的根是 1,每个节 点都代表树上的一个叶子. 如果你不知道什么叫树,你可以认为树是 ...
- ibatis常用16条SQL语句
(1) 输入参数为单个值 <delete id="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore" p ...
- 更改Visual Studio Code为中文字体最有效的方法
更改Visual Studio Code为中文字体最有效的方法. 网址: https://marketplace.visualstudio.com/search?target=VSCode& ...
- UVA - 12589 Learning Vector(dp-01背包)
题目: 思路: dp[j][h]表示选取了j个向量,且高度为h,利用01背包来解决问题. 没选当前的向量:dp[j][h] = dp[j][h]; 选了当前的向量:dp[j][h] = dp[j-1] ...
- Swoft 新手向教程 - 通过 Docker 搭建一个开发环境
本系列文章将从使用层面介绍 Swoft 框架的使用及业务开发,面向初中级的 PHPer Swoft首个基于 Swoole 原生协程的新时代 PHP 高性能协程全栈组件化框架,内置协程网络服务器及常用的 ...
- * average vector from multiple files--Matlab
n=359;a=[];b=[];c=[];% for loopfor i=1:n filename=sprintf('output_%d.dat',i); fileinfo = imp ...
- 【Codeforces 375A】Divisible by Seven
[链接] 我是链接,点我呀:) [题意] 让你把一个包含数字1,6,8,9的数字重新组合,使得组合成的数字能被7整除 [题解] 我们先提取出来1,6,8,9各1个 然后把剩余的len-4个数字除了0之 ...
- md5加密的工具类(from 韩顺平)
输入一个字符串,然后可以进行md5加密 import java.security.*; import java.security.spec.*; public class MyTools { publ ...
- PatentTips - Method for booting a host device from an MMC/SD device
FIELD OF THE INVENTION The present invention relates to a memory device and especially to the interf ...