原始对偶被卡成了 85pts 怎么办?
#include<bits/stdc++.h>
using namespace std;
template <class T> inline void read(T &x)
{
x = 0;
int f = 0;
char ch = getchar();
while(ch < '0' || ch > '9')
{
f |= ch == '-';
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = x * 10 + (ch - 48);
ch = getchar();
}
x = f ? -x : x;
return;
}
#define inf 0x3f3f3f3f
#define ll long long
#define N 505
int n, m, S, T;
int first[N], Next[N * N], to[N * N], cap[N * N], len[N * N], tot = 1;
inline void add(int x, int y, int z, int w)
{
Next[++tot] = first[x], first[x] = tot, to[tot] = y, cap[tot] = z, len[tot] = w;
Next[++tot] = first[y], first[y] = tot, to[tot] = x, cap[tot] = 0, len[tot] = -w;
return;
}
int cur[N], h[N];
int vis[N];
void init()
{
queue<int> Q;
while(!Q.empty()) Q.pop();
memset(h, 0x3f, sizeof(h));
h[S] = 0, vis[S] = 1, Q.push(S);
while(!Q.empty())
{
int u = Q.front();
Q.pop();
vis[u] = 0;
for(int i = first[u]; i; i = Next[i])
{
int v = to[i];
if(cap[i] > 0 && h[u] + len[i] < h[v])
{
h[v] = h[u] + len[i];
if(!vis[v]) vis[v] = 1, Q.push(v);
}
}
}
return;
}
priority_queue<pair<int, int>> q;
int dis[N];
bool dijkstra()
{
while(!q.empty()) q.pop();
memset(dis, 0x3f, sizeof(dis)), memset(vis, 0, sizeof(vis));
dis[S] = 0, q.push(make_pair(0, S));
while(!q.empty())
{
int u = q.top().second;
q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int i = first[u]; i; i = Next[i])
{
int v = to[i];
if(cap[i] > 0 && dis[u] + len[i] + h[u] - h[v] < dis[v])
{
dis[v] = dis[u] + len[i] + h[u] - h[v];
q.push(make_pair(-dis[v], v));
}
}
}
for(int i = 1; i <= T; i++) h[i] += dis[i];
return dis[T] != inf;
}
int sign;
int dfs(int u, int flow)
{
if(u == T) return flow;
vis[u] = sign;
int res = 0;
for(int &i = cur[u]; i; i = Next[i])
{
int v = to[i];
if(cap[i] > 0 && vis[v] != sign && len[i] + h[u] - h[v] == 0)
{
int delta = dfs(v, min(cap[i], flow - res));
if(delta) cap[i] -= delta, cap[i ^ 1] += delta, res += delta;
if(res == flow) break;
}
}
if(res != flow) vis[u] = sign;
return res;
}
pair<int, ll> mxflow()
{
init();
pair<int, ll> res = make_pair(0, 0);
while(dijkstra())
{
memcpy(cur, first, sizeof(first));
do
{
sign++;
int flow = dfs(S, inf);
if(!flow) break;
res.first += flow, res.second += 1ll * h[T] * flow;
} while(1);
}
return res;
}
int mem[N];
signed main()
{
read(n), read(m);
S = n + m + 1, T = S + 1;
int x, y;
for(int i = 1; i <= m; i++) read(x), add(n + i, T, x, 0);
for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++)
{
read(x);
if(x) add(i, n + j, inf, 0);
}
for(int i = 1; i <= n; i++)
{
read(x);
for(int j = 1; j <= x; j++) read(mem[j]);
mem[x + 1] = inf;
for(int j = 1; j <= x + 1; j++) read(y), add(S, i, mem[j] - mem[j - 1], y);
}
printf("%lld", mxflow().second);
return 0;
}