记录编号 |
62956 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[NOI 2012]美食节 |
最终得分 |
100 |
用户昵称 |
zycnever |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
1.688 s |
提交时间 |
2013-07-12 13:44:10 |
内存使用 |
6.44 MiB |
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <climits>
#include <iostream>
#include <queue>
#include <algorithm>
#define maxn 42
#define maxm 1020
#define maxp 8020
#define maxnode maxn + maxm + maxp
#define maxedge maxn * (maxm + maxp)
#define FOR(i, s, t) for (i = (s); i <= (t); ++i)
#define inf 1000000000
using namespace std;
int n, m, p[maxn], pall = 0, t[maxn][maxm];
int head[maxnode], next[maxedge], end[maxedge], flow[maxedge], cost[maxedge], id = -1;
int chefid[maxm], chefcnt[maxm], S, T, ndcnt, totcost = 0, fa[maxnode];
bool mrk[maxnode];
void read()
{
cin >> n >> m;
int i, j;
FOR(i, 1, n)
{
cin >> p[i];
pall += p[i];
}
FOR(i, 1, n) FOR(j, 1, m) cin >> t[i][j];
}
void add_edge(int u, int v, int f, int c)
{
++id;
next[id] = head[u];
end[id] = v;
flow[id] = f;
cost[id] = c;
head[u] = id;
++id;
next[id] = head[v];
end[id] = u;
flow[id] = 0;
cost[id] = -c;
head[v] = id;
}
void dymic_add(int j)
{
chefid[j] = ++ndcnt;
++chefcnt[j];
int i;
FOR(i, 1, n) add_edge(i, ndcnt, 1, chefcnt[j] * t[i][j]);
add_edge(ndcnt, T, 1, 0);
}
void build()
{
S = 0;
T = n + m + pall + 1;
int i;
ndcnt = n;
memset(head, -1, sizeof(head));
memset(next, -1, sizeof(next));
memset(chefcnt, 0, sizeof(chefcnt));
FOR(i, 1, n) add_edge(S, i, p[i], 0);
FOR(i, 1, m) dymic_add(i);
}
int dist[maxnode], d[maxnode];
bool in[maxnode];
bool relax(int u, int e)
{
int v = end[e];
if (dist[v] > dist[u] + cost[e])
{
dist[v] = dist[u] + cost[e];
fa[v] = u;
return true;
}
return false;
}
bool SPFA()
{
int i;
FOR(i, S, T) dist[i] = inf;
dist[S] = 0;
queue<int> q;
memset(in, false, sizeof(in));
q.push(S);
in[S] = true;
while (!q.empty())
{
int u = q.front();
q.pop();
in[u] = false;
for (int e = head[u]; e != -1; e = next[e])
{
int v = end[e];
if (flow[e] && relax(u, e) && !in[v])
{
in[v] = true;
q.push(v);
}
}
}
return dist[T] != inf;
}
int dfs(int u, int bef, int f)
{
if (u == T)
return f;
int tot = 0;
for (int e = head[u]; e != -1; e = next[e])
{
int v = end[e];
if (v == bef) continue;
int tmp;
if (flow[e] && fa[v] == u && (tmp = dfs(v, u, min(f, flow[e]))))
{
flow[e] -= tmp;
flow[e^1] += tmp;
f -= tmp;
tot += tmp;
totcost += cost[e] * tmp;
}
}
if (tot == 0)
dist[u] = -1;
return tot;
}
void dinic()
{
int i;
while (SPFA())
{
dfs(S, -1, inf);
FOR(i, 1, m) if (flow[head[chefid[i]]] == 0) dymic_add(i);
}
}
int main()
{
freopen("noi12_delicacy.in", "r", stdin);
freopen("noi12_delicacy.out", "w", stdout);
read();
build();
dinic();
cout << totcost << endl;
return 0;
}