网络流模版题:32ms
class Solution {
public:
struct Edge{
int from;
int to;
int flow;
int var;
int rvs;
int pre;
Edge(int a,int b,int c,int d,int e,int f):from(a),to(b),flow(c),var(d),rvs(e),pre(f){}
};
vector<Edge> E;
int cnt;
vector<int> pre;
vector<int> path;
vector<int> vis;
vector<int> dis;
int S,T;
void addEdge(int from,int to,int flow,int var){
E.push_back(Edge(from,to,flow,var,cnt+1,pre[from]));
pre[from] = cnt++;
E.push_back(Edge(to,from,0,-var,cnt-1,pre[to]));
pre[to] = cnt++;
}
bool SPFA(){
const int INF = 0x3f3f3f3f;
for(int i=0;i<=T;i++) path[i] = vis[i] = 0,dis[i] = INF;
queue<int> q;
q.push(S);
dis[S] = 0;
while(!q.empty()){
int now = q.front();
q.pop();
vis[now] = 0;
for(int i=pre[now];i!=0;i=E[i].pre){
if(E[i].flow > 0 && dis[now] + E[i].var < dis[E[i].to]){
dis[E[i].to] = dis[now] + E[i].var;
path[E[i].to] = i;
if(vis[E[i].to] == 0){
q.push(E[i].to);
vis[E[i].to] = 1;
}
}
}
}
if(dis[T] == INF) return false;
return true;
}
int DFS(){
const int INF = 0x3f3f3f3f;
int Eid = path[T];
int minflow = INF;
while(Eid != 0){
minflow = min(minflow,E[Eid].flow);
Eid = path[E[Eid].from];
}
Eid = path[T];
int ans = 0;
while(Eid != 0){
E[Eid].flow -= minflow;
E[E[Eid].rvs].flow += minflow;
ans += minflow*E[Eid].var;
Eid = path[E[Eid].from];
}
return ans;
}
int cherryPickup(vector<vector<int>>& grid) {
const int INF = 0x3f3f3f3f;
int N = grid.size();
int M = N*N;
S = M+M; T = S+1;
pre.reserve(T+1);
path.reserve(T+1);
vis.reserve(T+1);
dis.reserve(T+1);
for(int i=0;i<=T;i++) pre[i] = 0;
cnt = 1;
E.push_back(Edge(0,0,0,0,0,0));
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(grid[i][j] == -1) continue;
addEdge(i*N+j,i*N+j+M,1,-grid[i][j]);
addEdge(i*N+j,i*N+j+M,INF,0);
if(i!=0) addEdge((i-1)*N+j+M,i*N+j,INF,0);
if(j!=0) addEdge(i*N+j-1+M,i*N+j,INF,0);
}
}
addEdge(S,0,2,0);
addEdge(S-1,T,2,0);
int ans = 0;
while(SPFA()) ans+=DFS();
return -ans;
}
};