WA 12pts,请问能帮忙看一看吗?人已经麻了。
  • 板块P4003 无限之环
  • 楼主strcmp
  • 当前回复11
  • 已保存回复11
  • 发布时间2022/4/9 01:39
  • 上次更新2023/10/28 04:14:09
查看原帖
WA 12pts,请问能帮忙看一看吗?人已经麻了。
551861
strcmp楼主2022/4/9 01:39

样例全过,讨论区 datamaker 数据全过。debug 一个晚上了,请问是哪里写挂了?

#include <bits/stdc++.h>
using namespace std;
#define inf 1000000000000000
#define V 100100
#define E 500100
typedef long long int ll;
struct edge {
	int to, next;
	ll capa, cost;
};
int cnt = 0, head[V], n, m; edge node[E];
inline void add(int fir, int nxt, ll w, ll c) {
	node[cnt].to = nxt,
		node[cnt].capa = w,
		node[cnt].cost = c,
		node[cnt].next = head[fir],
		head[fir] = cnt++;
}
int s, t, cur[V]; deque<int>que; ll dep[V], sum = 0, cost = 0, rsum = 0;
bool vis[V];
inline bool spfa() {
	for (register int i = 1; i <= t; ++i)dep[i] = inf;
	dep[s] = 0; que.push_back(s); int u, v;
	while (!que.empty()) {
		v = que.front(); que.pop_front();
		for (register int i = head[v]; i != -1; i = node[i].next) {
			u = node[i].to;
			if (dep[v] + node[i].cost < dep[u] && node[i].capa) {
				dep[u] = dep[v] + node[i].cost;
				if (!que.empty() && dep[u] < dep[que.front()])que.push_front(u);
				else que.push_back(u);
			}
		}
	}
	return (dep[t] != inf);
}
ll dfs(register int v, register ll flow) {
	if (v == t || flow == 0)return flow; ll used = 0, wei = 0;
	vis[v] = true;
	for (register int i = cur[v]; i != -1; i = node[i].next) {
		cur[v] = i;
		if (!vis[node[i].to] && dep[node[i].to] == dep[v] + node[i].cost && node[i].capa) {
			wei = dfs(node[i].to, min(flow - used, node[i].capa));
			if (wei) {
				node[i].capa -= wei,
					node[i ^ 1].capa += wei,
					used += wei,
					cost += node[i].cost * wei;
			}
		}
		if (used == flow)break;
	}
	vis[v] = false;
	return used;
}
inline void Dinic() {
	while (spfa()) {
		memcpy(cur, head, (t + 1) * sizeof(int));
		sum += dfs(s, inf);
	}
}
inline void addE(int u, int v, ll w, ll c, bool col = true) {
	if (!col)swap(u, v);
	add(u, v, w, c);
	add(v, u, 0, -c);
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(); cout.tie();
	memset(head, -1, V * sizeof(int));
	cin >> n >> m; s = n * m * 5 + 1, t = n * m * 5 + 2;
	int f, l, v, dir = n * m; ll w, c; bool col;//黑为 true,白为 false
	//dir = n*m,dir*1 上,dir*2 右,dir*3 下,dir*4 左
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> w; v = (i - 1) * m + j;
			if (col = !(i + j & 1))addE(s, v, inf, 0, 1);
			else addE(v, t, inf, 0, 1);
			if (w & 1)addE(v, v + dir, 1, 0, col),++rsum;
			if (w & 2)addE(v, v + dir * 2, 1, 0, col),++rsum;
			if (w & 4)addE(v, v + dir * 3, 1, 0, col),++rsum;
			if (w & 8)addE(v, v + dir * 4, 1, 0, col),++rsum;
			if (col) {
				if (i - 1)addE(v + dir, v - m + dir * 3, 1, 0, col);//上
				if (j - 1)addE(v + dir * 4, v - 1 + dir * 2, 1, 0, col);//左
				if (i + 1 <= n)addE(v + dir * 3, v + m + dir, 1, 0, col);//下
				if (j + 1 <= m)addE(v + dir * 2, v + 1 + dir * 4, 1, 0, col);//右
			}
			switch (w) {
			case 0:break;
			case 1: {//0001,上有接头
				addE(v + dir, v + dir * 4, 1, 1, col);
				addE(v + dir, v + dir * 2, 1, 1, col);
				addE(v + dir, v + dir * 3, 1, 2, col);
				break;
			}
			case 2: {//0010,右有接头
				addE(v + dir * 2, v + dir, 1, 1, col);
				addE(v + dir * 2, v + dir * 4, 1, 2, col);
				addE(v + dir * 2, v + dir * 3, 1, 1, col);
				break;
			}
			case 3: {//0011,上右有接头
				addE(v + dir, v + dir * 3, 1, 1, col);//上连下
				addE(v + dir * 2, v + dir * 4, 1, 1, col);//右连左
				break;
			}
			case 4: {//0100,下有接头
				addE(v + dir * 3, v + dir * 2, 1, 1, col);
				addE(v + dir * 3, v + dir * 4, 1, 1, col);
				addE(v + dir * 3, v + dir, 1, 2, col);
				break;
			}
			case 5: {//0101,上下有接头
				if (i - 1)addE(v + dir, v - m + dir * 3, 1, 0, col);
				if (i + 1 <= n)addE(v + dir * 4, v + m + dir, 1, 0, col);
				break;
			}
			case 6: {//0110,下右有接头
				addE(v + dir * 3, v + dir, 1, 1, col);//下连上
				addE(v + dir * 2, v + dir * 4, 1, 1, col);//右连左
				break;
			}
			case 7: {//0111,上下右有接头
				addE(v + dir, v + dir * 4, 1, 1, col);
				addE(v + dir * 2, v + dir * 4, 1, 2, col);
				addE(v + dir * 3, v + dir * 4, 1, 1, col);
				break;
			}
			case 8: {//1000,左有接头
				addE(v + dir * 4, v + dir, 1, 1, col);
				addE(v + dir * 4, v + dir * 2, 1, 2, col);
				addE(v + dir * 4, v + dir * 3, 1, 1, col);
				break;
			}
			case 9: {//1001,上左有接头
				addE(v + dir * 4, v + dir * 2, 1, 1, col);
				addE(v + dir, v + dir * 3, 1, 1, col);
				break;
			}
			case 10: {//1010,左右有接头
				if (j - 1)addE(v + dir * 2, v - 1 + dir * 4, 1, 0, col);
				if (j + 1 <= m)addE(v + dir * 4, v + 1 + dir * 2, 1, 0, col);
				break;
			}
			case 11: {//1011,左右上有接头
				addE(v + dir * 4, v + dir * 3, 1, 1, col);
				addE(v + dir, v + dir * 3, 1, 2, col);
				addE(v + dir * 2, v + dir * 3, 1, 1, col);
				break;
			}
			case 12: {//1100,下左有接头
				addE(v + dir * 3, v + dir, 1, 1, col);
				addE(v + dir * 4, v + dir * 2, 1, 1, col);
				break;
			}
			case 13: {//1101,上下左有接头
				addE(v + dir * 4, v + dir * 2, 1, 2, col);
				addE(v + dir, v + dir * 2, 1, 1, col);
				addE(v + dir * 3, v + dir * 2, 1, 1, col);
				break;
			}
			case 14: {//1110,下左右有接头
				addE(v + dir * 4, v + dir, 1, 1, col);
				addE(v + dir * 3, v + dir, 1, 2, col);
				addE(v + dir * 2, v + dir, 1, 1, col);
				break;
			}
			case 15: break;
			}
		}
	}
	Dinic();
	if (sum * 2 != rsum)cout << "-1";
	else cout << cost;
	return 0;
}
2022/4/9 01:39
加载中...