求助 WA 40pts
查看原帖
求助 WA 40pts
91127
_5011_楼主2020/12/30 19:34
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1 << 21], *p1 = buf, *p2 = buf;

inline int qread() {
	register char c = getchar();
	register int x = 0, f = 1;
	while (c < '0' || c > '9') {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		x = (x << 3) + (x << 1) + c - 48;
		c = getchar();
	}
	return x * f;
}

inline long long Abs(const long long& x) {return (x > 0 ? x : -x);}
inline long long Max(const long long& x, const long long& y) {return (x > y ? x : y);}
inline long long Min(const long long& x, const long long& y) {return (x < y ? x : y);}

const long long INF = 0x3f3f3f3f3f3f3f3f;
struct Edge {
	int to, nxt;
	long long cap, cost;
	Edge() {
		nxt = -1;
	}
};
int n, m, hd[1000005], pnt, psum, t[45][105];
Edge e[10000005];

inline void AddEdge(int u, int v, long long cap, long long cost) {
	//printf("%d->%d %lld\n", u, v, cost);
	e[pnt].to = v;
	e[pnt].cap = cap;
	e[pnt].cost = cost;
	e[pnt].nxt = hd[u];
	hd[u] = pnt;
	pnt++;
	e[pnt].to = u;
	e[pnt].cap = 0;
	e[pnt].cost = -cost;
	e[pnt].nxt = hd[v];
	hd[v] = pnt;
	pnt++;
}

inline int Pid(int d, int rk) {return n + (d - 1) * psum + rk;}
inline int D(int pid) {return (pid - n - 1) / psum + 1;}
inline int Rk(int pid) {return (pid - n - 1) % psum + 1;}

namespace MCMF {
	long long dis[1000005];
	bool inq[1000005], mrk[1000005];
	int top[1000005];
	inline void SPFA(int s) {
		queue <int> que;
		que.push(s);
		memset(dis, 0x3f, sizeof(dis));
		dis[s] = 0;
		while (!que.empty()) {
			int u = que.front();
			que.pop();
			inq[u] = 0;
			for (int i = hd[u];~i;i = e[i].nxt) {
				if (e[i].cap && dis[e[i].to] > dis[u] + e[i].cost) {
					dis[e[i].to] = dis[u] + e[i].cost;
					if (!inq[e[i].to]) {
						inq[e[i].to] = 1;
						que.push(e[i].to);
					}
				}
			}
		}
	}
	inline long long Dfs(int u, int t, long long f) {
		if (u == t) return f;
		mrk[u] = 1;
		long long flw = 0;
		for (int i = hd[u];~i;i = e[i].nxt) {
			if (e[i].cap && dis[e[i].to] == dis[u] + e[i].cost && !mrk[e[i].to]) {
				long long d = Dfs(e[i].to, t, Min(f - flw, e[i].cap));
				if (d) {
					flw += d;
					e[i].cap -= d;
					e[i ^ 1].cap += d; 
				} else dis[e[i].to] = INF;
				if (flw == f) break;
			}
		}
		mrk[u] = 0;
		return flw;
	}
	inline long long Flow(int S, int T) {
		for (int i = 1;i <= n;i++) top[i] = 1;
		long long ans = 0, flw = 0;
		while (flw < psum) {
			SPFA(S);
			long long cur = Dfs(S, T, INF);
			flw += cur;
			ans += dis[T] * cur;
			printf("%lld %lld %lld\n", cur, flw, ans);
			for (int i = hd[T];~i;i = e[i].nxt) {
				int d = D(e[i].to), rk = Rk(e[i].to);
				if (rk == top[d] && top[d] != psum && e[i ^ 1].cap == 0) {
					top[d]++;
					//printf("(%d,%d)\n", d, top[d]);
					AddEdge(Pid(d, top[d]), T, 1, 0);
					for (int j = 1;j <= n;j++) AddEdge(j, Pid(d, top[d]), 1, 1ll * t[j][d] * top[d]);
				}
			}
		}
		return ans;
	}
}

inline void Read() {
	n = qread(); m = qread();
	for (int i = 1;i <= n;i++) {
		int p = qread();
		psum += p;
		AddEdge(0, i, p, 0);
	}
	for (int i = 1;i <= n;i++) {
		for (int j = 1;j <= m;j++) {
			t[i][j] = qread();
			AddEdge(i, Pid(j, 1), 1, t[i][j]);
			if (i == 1) AddEdge(Pid(j, 1), n + m * psum + 1, 1, 0);
		}
	}
}

int main() {
	memset(hd, -1, sizeof(hd));
	Read();
	//puts("---");
	printf("%lld", MCMF::Flow(0, n + m * psum + 1));
	#ifndef ONLINE_JUDGE
	while (1);
	#endif
	return 0;
}

2020/12/30 19:34
加载中...