费用流求助
查看原帖
费用流求助
667448
go_deeper楼主2023/11/17 19:57

为什么费用流不拆点过不了,就是一个点向它的下一个点连两条边,一条边容量为 11,费用为 −w-w, 另一条边容量为 inf,费用为 00。

struct MCFGraph {
	struct Edge {
		int v;
		long long c, f;
		Edge(int v, long long c, long long f) : v(v), c(c), f(f) {}
	};
	const int n;
	std::vector<Edge> e;
	std::vector<std::vector<int>> g;
	std::vector<long long> h, dis;
	std::vector<int> pre;
	bool dijkstra(int s, int t) {
		dis.assign(n, std::numeric_limits<long long>::max());
		pre.assign(n, -1);
		std::priority_queue<std::pair<long long, int>, std::vector<std::pair<long long, int>>, std::greater<std::pair<long long, int>>> que;
		dis[s] = 0;
		que.emplace(0, s);
		while (!que.empty()) {
			long long d = que.top().first;
			int u = que.top().second;
			que.pop();
			if (dis[u] < d) continue;
			for (int i : g[u]) {
				int v = e[i].v;
				long long c = e[i].c;
				long long f = e[i].f;
				if (c > 0 && dis[v] > d + h[u] - h[v] + f) {
					dis[v] = d + h[u] - h[v] + f;
					pre[v] = i;
					que.emplace(dis[v], v);
				}
			}
		}
		return dis[t] != std::numeric_limits<long long>::max();
	}
	MCFGraph(int n) : n(n), g(n) {}
	void addEdge(int u, int v, int w, int c) {
		if (c < 0) {
			g[u].push_back(e.size());
			e.emplace_back(v, 0, c);
			g[v].push_back(e.size());
			e.emplace_back(u, w, -c);
		} else {
			g[u].push_back(e.size());
			e.emplace_back(v, w, c);
			g[v].push_back(e.size());
			e.emplace_back(u, 0, -c);
		}
	}
	std::pair<long long, long long> flow(int s, int t) {
		long long flow = 0;
		long long cost = 0;
		h.assign(n, 0);
		while (dijkstra(s, t)) {
			for (int i = 0; i < n; ++i) h[i] += dis[i];
			long long aug = std::numeric_limits<long long>::max();
			for (int i = t; i != s; i = e[pre[i] ^ 1].v) aug = std::min(aug, e[pre[i]].c);
			for (int i = t; i != s; i = e[pre[i] ^ 1].v) {
				e[pre[i]].c -= aug;
				e[pre[i] ^ 1].c += aug;
			}
			flow += aug;
			cost += (long long)(aug) * h[t];
		}
		return std::make_pair(flow, cost);
	}
};

int w[55][55];
void solve(){
    int n,m,a,b,c;
    cin>>n;
    auto idx=[&](int x,int y)
    {
        return (x-1)*n+y;
    };
    while(cin>>a>>b>>c)
    {
        if(!a&&!b&&!c)break;
        w[a][b]=c;
    }
    MCFGraph e(5001);
    e.addEdge(0,1,2,0);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i+1<=n)
            {
                e.addEdge(idx(i,j),idx(i+1,j),1,-w[i+1][j]);
                e.addEdge(idx(i,j),idx(i+1,j),int_inf,0);
            }
            if(j+1<=n)
            {
                e.addEdge(idx(i,j),idx(i,j+1),1,-w[i][j+1]);
                e.addEdge(idx(i,j),idx(i,j+1),int_inf,0);
            }
        }
    }
    e.addEdge(idx(n,n),5000,int_inf,0);
    auto[f,cc]=e.flow(0,5000);
    writeln(w[1][1]-e.flow(0,5000).second);
}
2023/11/17 19:57
加载中...