马蜂优良 EK+SPFA 4TLE 求条
查看原帖
马蜂优良 EK+SPFA 4TLE 求条
551417
CommonDigger楼主2025/1/30 10:07

rt. 后面四个大数据点T了

/*
Luogu P3381 Minimum Cost & Maximum Flow
https://www.luogu.com.cn/problem/P3381
*/
#include <iostream>
#include <cstring>
#include <queue>
#define INF 2147483647
#define int long long
using namespace std;
const int N=5005, M=50005;
int n, m, S, T, temp1, temp2, temp3, temp4;
int head[N], dis[N], pre[N], idx=1, C, ans; // pre记录每个点之前的边
bool vis[N];
struct edge{
	int to, nxt, w, c;
}e[2*M];
int min2(int x, int y){
	return x<y ? x : y;
}
void add_edge(int u, int v, int w, int c){
	e[++idx].to=v;
	e[idx].w=w;
	e[idx].c=c;
	e[idx].nxt=head[u];
	head[u]=idx;
	e[++idx].to=u;
	e[idx].w=0;
	e[idx].c=-c;
	e[idx].nxt=head[v];
	head[v]=idx;
}
bool spfa(){
	for(int i=1;i<=n;i++) dis[i]=INF, vis[i]=false;
	dis[S]=0;
	queue<int>q;
	q.push(S);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		vis[x] = false;
		for(int i=head[x]; i; i=e[i].nxt){
			int to=e[i].to;
			if(dis[to] > dis[x]+e[i].c && e[i].w){
				dis[to] = dis[x]+e[i].c;
				if(!vis[to]){
					vis[to]=true;
					pre[to] = i;
					q.push(to);
				}
			}
		}
	}
	return dis[T] != INF;
}
void EK(){
	while(spfa()){
		int min_flow = INF;
		for(int walker=T; walker!=S; walker=e[pre[walker]^1].to){
			min_flow = min2(min_flow, e[pre[walker]].w);
		}
		for(int walker=T; walker!=S; walker=e[pre[walker]^1].to){
			e[pre[walker]].w -= min_flow;
			e[pre[walker]^1].w += min_flow;
			C += e[pre[walker]].c * min_flow;
		}
		ans += min_flow;
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m >> S >> T;
	for(int i=1;i<=m;i++){
		cin >> temp1 >> temp2 >> temp3 >> temp4;
		add_edge(temp1, temp2, temp3, temp4);
	}
	EK();
	cout << ans << " " << C;
}
2025/1/30 10:07
加载中...