acdream--Matrix sum
来源:互联网 发布:学生购买阿里云服务器 编辑:程序博客网 时间:2024/06/06 02:00
Problem Description
sweet和zero在玩矩阵游戏,sweet画了一个N * M的矩阵,矩阵的每个格子有一个整数。zero给出N个数Ki,和M个数Kj,zero要求sweet选出一些数,满足从第 i 行至少选出了Ki个数,第j列至少选出了Kj个数。 这些数之和就是sweet要付给zero的糖果数。sweet想知道他至少要给zero多少个糖果,您能帮他做出一个最优策略吗?
Input
首行一个数T(T <= 40),代表数据总数,接下来有T组数据。
每组数据:
第一行两个数N,M(1 <= N,M <= 50)
接下来N行,每行M个数(范围是0-10000的整数)
接下来一行有N个数Ki,表示第i行至少选Ki个元素(0 <= Ki <= M)
最后一行有M个数Kj,表示第j列至少选Kj个元素(0 <= Kj <= N)
Output
每组数据输出一行,sweet要付给zero的糖果数最少是多少
Sample Input
14 41 1 1 11 10 10 101 10 10 101 10 10 101 1 1 11 1 1 1
Sample Output
6
思路:超源向行连边,容量为m-Ki,费用为0.列向超汇连边,容量为n-Kj,费用为0.行列连容量为1,费用为-key的边。当spfa找到的路径cost>=0就可停止。
#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define maxn 3800#define maxm 48000#define inf 0x3f3f3f3fint first[maxn];int key[108][108];int vv[maxm],ww[maxm],nxt[maxm],cst[maxm];int e;int pre[maxn],pos[maxn];int dis[maxn],que[maxn*10];bool vis[maxn];inline int min(int a,int b){ return a > b?b:a;}void addEdge(int u,int v,int w,int cost){ vv[e] = v; ww[e] = w; cst[e] = cost; nxt[e] = first[u]; first[u] = e++; vv[e] = u; ww[e] = 0; cst[e] = -cost; nxt[e] = first[v]; first[v] = e++;} int spfa(int s,int t){ memset(pre,-1,sizeof(pre)); memset(vis,0,sizeof(vis)); int head,tail; head = tail = 0; for(int i = 0;i < maxn;i++) dis[i] = inf; que[tail++] = s; pre[s] = s; dis[s] = 0; vis[s] = 1; while(head < tail) { int u = que[head++]; vis[u] = 0; for(int i = first[u];i != -1;i = nxt[i]) { int v = vv[i]; if(ww[i] > 0 && dis[u] + cst[i] < dis[v]) { dis[v] = dis[u] + cst[i]; pre[v] = u; pos[v] = i; if(!vis[v]) { vis[v] = 1; que[tail++] = v; } } } } return pre[t] != -1;} int MinCostFlow(int s,int t,int flow){ int cost = 0; int nowflow = 0; while(spfa(s,t)) { int f = inf; for(int i = t;i != s;i = pre[i]) if(ww[pos[i]] < f) f = ww[pos[i]]; if(dis[t] >= 0) break; f = min(flow - nowflow,f); nowflow += f; cost += dis[t]*f; for(int i = t;i != s;i = pre[i]) { ww[pos[i]] -= f; ww[pos[i]^1] += f; } if(nowflow == flow) break; } return cost;}int main(){ //freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); e = 0; memset(first,-1,sizeof(first)); int sum = 0; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { int a; scanf("%d",&a); sum += a; addEdge(i,n+j,1,-a); } } for(int i = 1;i <= n;i++) { int a; scanf("%d",&a); addEdge(0,i,m-a,0); } for(int i = 1;i <= m;i++) { int a; scanf("%d",&a); addEdge(n+i,n+m+1,n-a,0); } int fuck = MinCostFlow(0,n+m+1,inf); printf("%d\n",sum+fuck); }}
0 0
- acdream--Matrix sum
- acdream 1171 Matrix sum
- [费用流] acdream 1171 Matrix sum
- Acdream 1171 Matrix sum 上下界费用流
- ACdream-1171 Matrix sum, 最大费用最大流
- ACdream 1171 Matrix sum (有界费用流)
- ACdream-1171 Matrix sum, 最大费用最大流
- ACdream: Sum
- ACdream 1213 Matrix Multiplication
- ACdream 1213 Matrix Multiplication
- acdream(16) J-Sum
- ACdream 1154 Lowbit Sum
- ACdream 1156_LCP SUM
- ACdream P1174 Sum
- Matrix Sum
- ACdream 1139(Sum-逆元)
- ACdream OJ 1154 Lowbit Sum
- acdream 1431 Sum vs Product
- js和C# 判断时间段内早中晚问候语
- 1.8-s2是否是s1的rotation(调用一次isSubstring)
- 原形设计の学习笔记(一)
- JAVA 实现二叉树 递归
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- acdream--Matrix sum
- 关于内存映射来修改文件,并改变文件的大小
- SQL Error: 17059, SQLState: 99999 错误原因
- Codeforces #259 (Div. 2) B. Little Pony and Sort by Shift
- jordan shoes discount options is beneficial
- [水]ZOJ1016
- hdu1201-18岁生日
- shell程序设计笔记
- 进制转换(2031)