Jam's store
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 8 Accepted Submission(s): 3
Problem Description
Jam didn't study well,then he go to repair the computer in a store,there are
M
staffs and
N
guests, given each guests have to spend
Tij
time to repair the computer by the
j
staffs.
Now ask the total of time the guest at least to wait.
The staff wiil do the next work after he has done the current work
Now ask the total of time the guest at least to wait.
The staff wiil do the next work after he has done the current work
Input
The first line is
T(1≤T≤100)
means
T
Case
For each case
The first line is M and N(1≤M,N≤20) means the number of staffs and guests
Now given a Matrix with N∗M each number means the i guests to the j staff time (1≤Tij≤1000)
For each case
The first line is M and N(1≤M,N≤20) means the number of staffs and guests
Now given a Matrix with N∗M each number means the i guests to the j staff time (1≤Tij≤1000)
Output
Output one line about the time at least they need to wait
Sample Input
1 4 3 4 4 1 5 8 2 5 6 4 5 10 5
Sample Output
7Hintthe first guest choose the third staff the second guest choose the second staff the third gurst choose the third staff the total of time is 4+2+1=7
题意:有n个顾客和m个店员,给出一个n*m矩阵(i, j)元素表示i顾客找j店员修理电脑的时间。问你所有顾客需要等待的最小时间和。
思路:很裸的费用流,由于题目没有说明每个店员必须修理电脑,那么我们就把店员拆成n*m个点,分别表示第i个顾客是第k个来找j店员修理电脑,正向来建边不好处理,倒着来,倒数第k个,那么后面k个(包括他)需要等待时间和k*time[i][j]。建好图跑出费用流就可以了。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <string>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (5000+10)
#define MAXM (800000+10)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while((a)--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
#pragma comment(linker, "/STACK:102400000,102400000")
#define fi first
#define se second
using namespace std;
struct Edge{
int from, to, cap, flow, cost, next;
};
Edge edge[MAXM];
int head[MAXN], edgenum;
int pre[MAXN], dist[MAXN];
bool vis[MAXN];
void init(){
edgenum = 0;
CLR(head, -1);
}
void addEdge(int u, int v, int w, int c)
{
Edge E = {u, v, w, 0, c, head[u]};
edge[edgenum] = E;
head[u] = edgenum++;
Edge E1 = {v, u, 0, 0, -c, head[v]};
edge[edgenum] = E1;
head[v] = edgenum++;
}
bool BFS(int s, int t)
{
queue<int> Q;
CLR(dist, INF); CLR(pre, -1);
CLR(vis, false);
dist[s] = 0; vis[s] = true; Q.push(s);
while(!Q.empty())
{
int u = Q.front();
Q.pop();
vis[u] = false;
for(int i = head[u]; i != -1; i = edge[i].next)
{
Edge E = edge[i];
if(dist[E.to] > dist[u] + E.cost && E.cap > E.flow)
{
dist[E.to] = dist[u] + E.cost;
pre[E.to] = i;
if(!vis[E.to])
{
vis[E.to] = true;
Q.push(E.to);
}
}
}
}
return pre[t] != -1;
}
void MCMF(int s, int t, int &cost, int &flow)
{
cost = flow = 0;
while(BFS(s, t))
{
int Min = INF;
for(int i = pre[t]; i != -1; i = pre[edge[i^1].to])
{
Edge E = edge[i];
Min = min(Min, E.cap - E.flow);
}
for(int i = pre[t]; i != -1; i = pre[edge[i^1].to])
{
edge[i].flow += Min;
edge[i^1].flow -= Min;
cost += Min * edge[i].cost;
}
flow += Min;
}
}
int main()
{
int t; Ri(t);
W(t)
{
int n, m; Ri(m); Ri(n);
int S = 0, T = n+n*m+1; init();
for(int i = 1; i <= n; i++)
{
addEdge(S, i, 1, 0);
for(int j = 1; j <= m; j++)
{
int time; Ri(time);
for(int k = 1; k <= n; k++)
addEdge(i, j*n+k, 1, k*time);
}
}
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
addEdge(i*n+j, T, 1, 0);
int flow, cost; MCMF(S, T, cost, flow);
Pi(cost);
}
return 0;
}