http://acm.hdu.edu.cn/showproblem.php?pid=4975

给出每行每列的和,问是否存在这样的表格;每个小格放的数字只能是0--9。

直接用第八场最大流模板.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <numeric>
using namespace std;
typedef long long LL; const int MAXN = 610;
const int MAXV = MAXN << 1;
const int MAXE = 2 * MAXN * MAXN;
const int INF = 0x3f3f3f3f; struct ISAP {
int head[MAXV], cur[MAXV], gap[MAXV], dis[MAXV], pre[MAXV];
int to[MAXE], next[MAXE], flow[MAXE];
int n, ecnt, st, ed; void init(int n) {
this->n = n;
memset(head + 1, -1, n * sizeof(int));
ecnt = 0;
} void add_edge(int u, int v, int c) {
to[ecnt] = v; flow[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; flow[ecnt] = 0; next[ecnt] = head[v]; head[v] = ecnt++;
} void bfs() {
memset(dis + 1, 0x3f, n * sizeof(int));
queue<int> que; que.push(ed);
dis[ed] = 0;
while(!que.empty()) {
int u = que.front(); que.pop();
gap[dis[u]]++;
for(int p = head[u]; ~p; p = next[p]) {
int v = to[p];
if(flow[p ^ 1] && dis[u] + 1 < dis[v]) {
dis[v] = dis[u] + 1;
que.push(v);
}
}
}
} int max_flow(int ss, int tt) {
st = ss, ed = tt;
int ans = 0, minFlow = INF;
for(int i = 0; i <= n; ++i) {
cur[i] = head[i];
gap[i] = 0;
}
bfs();
int u = pre[st] = st;
while(dis[st] < n) {
bool flag = false;
for(int &p = cur[u]; ~p; p = next[p]) {
int v = to[p];
if(flow[p] && dis[u] == dis[v] + 1) {
flag = true;
minFlow = min(minFlow, flow[p]);
pre[v] = u;
u = v;
if(u == ed) {
ans += minFlow;
while(u != st) {
u = pre[u];
flow[cur[u]] -= minFlow;
flow[cur[u] ^ 1] += minFlow;
}
minFlow = INF;
}
break;
}
}
if(flag) continue;
int minDis = n - 1;
for(int p = head[u]; ~p; p = next[p]) {
int &v = to[p];
if(flow[p] && dis[v] < minDis) {
minDis = dis[v];
cur[u] = p;
}
}
if(--gap[dis[u]] == 0) break;
++gap[dis[u] = minDis + 1];
u = pre[u];
}
return ans;
} int stk[MAXV], top;
bool sccno[MAXV], vis[MAXV]; bool dfs(int u, int f, bool flag) {
vis[u] = true;
stk[top++] = u;
for(int p = head[u]; ~p; p = next[p]) if(flow[p]) {
int v = to[p];
if(v == f) continue;
if(!vis[v]) {
if(dfs(v, u, flow[p ^ 1])) return true;
} else if(!sccno[v]) return true;
}
if(!flag) {
while(true) {
int x = stk[--top];
sccno[x] = true;
if(x == u) break;
}
}
return false;
} bool acycle() {
memset(sccno + 1, 0, n * sizeof(bool));
memset(vis + 1, 0, n * sizeof(bool));
top = 0;
return dfs(ed, 0, 0);
}
} G; int row[MAXN], col[MAXN];
int mat[MAXN][MAXN];
int n, m, k, ss, tt; void solve() {
int sumr = accumulate(row + 1, row + n + 1, 0);
int sumc = accumulate(col + 1, col + m + 1, 0);
if(sumr != sumc) {
puts("So naive!");
return ;
}
int res = G.max_flow(ss, tt);
if(res != sumc) {
puts("So naive!");
return ;
}
if(G.acycle()) {
puts("So young!");
} else {
puts("So simple!");
// for(int i = 1; i <= n; ++i) {
// for(int j = 1; j < m; ++j) printf("%d ", G.flow[mat[i][j]]);
// printf("%d\n", G.flow[mat[i][m]]);
// }
}
} int main() {
int _;
scanf("%d",&_);
for(int cas = 1;cas <= _;++cas)
{
printf("Case #%d: ",cas);
scanf("%d%d", &n, &m );
k = 9;
for(int i = 1; i <= n; ++i) scanf("%d", &row[i]);
for(int i = 1; i <= m; ++i) scanf("%d", &col[i]);
ss = n + m + 1, tt = n + m + 2;
G.init(tt);
for(int i = 1; i <= n; ++i) G.add_edge(ss, i, row[i]);
for(int i = 1; i <= m; ++i) G.add_edge(n + i, tt, col[i]);
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
mat[i][j] = G.ecnt ^ 1;
G.add_edge(i, n + j, k);
}
}
solve();
}
}

hdu 4975 最大流快版的更多相关文章

  1. hdu 4975 最大流解决行列和求矩阵问题,用到矩阵dp优化

    //刚开始乱搞. //网络流求解,如果最大流=所有元素的和则有解:利用残留网络判断是否唯一, //方法有两种,第一种是深搜看看是否存在正边权的环,见上一篇4888 //至少四个点构成的环,第二种是用矩 ...

  2. HDU 1532 最大流入门

    1.HDU 1532 最大流入门,n个n条边,求第1点到第m点的最大流.只用EK做了一下. #include<bits/stdc++.h> using namespace std; #pr ...

  3. hdu 4975 A simple Gaussian elimination problem 最大流+找环

    原题链接 http://acm.hdu.edu.cn/showproblem.php?pid=4975 这是一道很裸的最大流,将每个点(i,j)看作是从Ri向Cj的一条容量为9的边,从源点除法连接每个 ...

  4. hdu 4975 A simple Gaussian elimination problem.(网络流,推断矩阵是否存在)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4975 Problem Description Dragon is studying math. One ...

  5. hdu 4289 最大流拆点

    大致题意:     给出一个又n个点,m条边组成的无向图.给出两个点s,t.对于图中的每个点,去掉这个点都需要一定的花费.求至少多少花费才能使得s和t之间不连通. 大致思路:     最基础的拆点最大 ...

  6. hdu - 4975 - A simple Gaussian elimination problem.(最大流量)

    意甲冠军:要在N好M行和列以及列的数字矩阵和,每个元件的尺寸不超过9,询问是否有这样的矩阵,是独一无二的N(1 ≤ N ≤ 500) , M(1 ≤ M ≤ 500). 主题链接:http://acm ...

  7. Going Home HDU - 1533 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 给一个网格图,每两个点之间的匹配花费为其曼哈顿距离,问给每个的"$m$"匹配到一个&q ...

  8. hdu 4888 最大流慢板

    http://acm.hdu.edu.cn/showproblem.php?pid=4888 添加一个源点与汇点,建图如下: 1. 源点 -> 每一行对应的点,流量限制为该行的和 2. 每一行对 ...

  9. hdu 3338 最大流 ****

    题意: 黑格子右上代表该行的和,左下代表该列下的和 链接:点我 这题可以用网络流做.以空白格为节点,假设流是从左流入,从上流出的,流入的容量为行和,流出来容量为列和,其余容量不变.求满足的最大流.由于 ...

随机推荐

  1. hdu 2066 ( 最短路) Floyd & Dijkstra & Spfa

    http://acm.hdu.edu.cn/showproblem.php?pid=2066 今天复习了一下最短路和最小生成树,发现居然闹了个大笑话-----我居然一直写的是Floyd,但我自己一直以 ...

  2. CF Round #509 (Div. 2)

    前言:第一次打\(CF\),因为经验不足以及英语水平很烂,即便在机房大佬的带领下也是花了好久才读懂题目..\(A\)题直到\(11\)分钟才\(A\),题目一共才做了\(4\)题,太菜了.. A. H ...

  3. BZOJ1912或洛谷3629 [APIO2010]巡逻

    一道树的直径 BZOJ原题链接 洛谷原题链接 显然在原图上路线的总长为\(2(n-1)\). 添加第一条边时,显然会形成一个环,而这条环上的所有边全部只需要走一遍.所以为了使添加的边的贡献最大化,我们 ...

  4. DEDE 首页调用指定栏目链接的代码

    {dede:type typeid='6'} <a href='[field:typelink /]' target="_blank" >更多</a> {/ ...

  5. 用PS绘制立体字的效果教程

    1. 新建一个透明画布. 2. 利用选区绘制一个圆圈 3. 利用渐变工具绘制渐变 (颜色自拟) 4. 选择混合器画笔工具按住ALT 点击填充颜色的图层 5. 新建画布填充黑色 利用混合画笔进行绘制. ...

  6. Python之路(第十二篇)程序解耦、模块介绍\导入\安装、包

    一.程序解耦 解耦总的一句话来说,减少依赖,抽象业务和逻辑,让各个功能实现独立. 直观理解“解耦”,就是我可以替换某个模块,对原来系统的功能不造成影响.是两个东西原来互相影响,现在让他们独立发展:核心 ...

  7. JDK8集合类源码解析 - ArrayList

    ArrayList主要要注意以下几点: 1构造方法 2添加add(E e) 3 获取 get(int index) 4 删除 remove(int index)    ,   remove(Objec ...

  8. javabean为什么需要序列化

    无论用hibernate或者mybatis结合spring做开发还是其他,系统里持久类往往要实现序列化, implements Serializable.我还是比较好奇,为什么要这样做呢?一直只知道个 ...

  9. chattr改变文件属性

    Linux chattr命令用于改变文件属性. 这项指令可改变存放在ext2文件系统上的文件或目录属性,这些属性共有以下8种模式: a:让文件或目录仅供附加用途. b:不更新文件或目录的最后存取时间. ...

  10. 2018.10.27 bzoj3209: 花神的数论题(数位dp)

    传送门 数位dpdpdp经典题. 题面已经暗示了我们按照二进制位来数位dpdpdp. 直接dpdpdp多少个数有111个111,222个111,333个111-, 然后快速幂算就行了. 于是我们枚举前 ...