63pts,求调,玄关
查看原帖
63pts,求调,玄关
528926
porse114514楼主2024/7/23 19:25
#include<bits/stdc++.h>
using namespace std;
#define man max
#define men min
#define int long long
const int maxn = 5010,INF = 11451419198102425;
struct edge{
	int to,v,costt;
};
int n,m,s,t,a,b,c,d,u,tt,ans = 0,minn,ff,maxflow;
short indexx[maxn][maxn];
edge now;
int q[maxn << 10],head,tail,dist[maxn],pree[maxn],sum[maxn];
vector<edge> G[maxn],g[maxn],stepG[maxn],stepg[maxn];
void input()
{
	cin >> n >> m;
	s = 1,t = n;
	for(int i = 1;i <= m;i++)
	{
		cin >> a >> b >> c >> d;
		indexx[a][b] = G[a].size();
		G[a].push_back({b,c,d});
		g[a].push_back({b,c,-1 * d});
		indexx[b][a] = G[b].size();
		G[b].push_back({a,0,d});
		g[b].push_back({a,0,-1 * d});
	}
}
void makestepgraph()
{
	for(int i = 1;i <= n;i++)
	{
		stepG[i].clear();
		stepg[i].clear();
		dist[i] = 0;
	}
	head = 1;
	tail = 1;
	q[1] = s;
	dist[s] = 1;
	while(head <= tail)
	{
		u = q[head++];
		for(int i = 0;i < G[u].size();i++)
		{
			now = G[u][i];
			if(!now.v) continue;
			if(dist[now.to] && dist[now.to] != dist[u] + 1) continue;
			if(!dist[now.to])
			{
				q[++tail] = now.to;
				dist[now.to] = dist[u] + 1;
			}
			stepG[u].push_back(now);
			stepg[u].push_back(now);
		}
	}
	/*for(int i = 1;i <= n;i++)
	{
		for(int j = 0;j < stepG[i].size();j++)
		{
			cout << i << ' ' << stepG[i][j].to << ' ' << stepG[i][j].v << ' ' << stepG[i][j].costt << '\n';
		}
	}*/
}
void SPFA()
{
	for(int i = 1;i <= n;i++)
	{
		dist[i] = INF;
	}
	dist[s] = 0;
	head = 1;
	tail = 1;
	q[1] = s;
	while(head <= tail)
	{
		u = q[head++];
		//cout << u << ' ';
		for(int i = 0;i < stepG[u].size();i++)
		{
			now = stepG[u][i];
			if(!now.v) continue;
			if(dist[now.to] <= dist[u]) continue;
			if(dist[u] + now.costt < dist[now.to])
			{
				dist[now.to] = dist[u] + now.costt;
				pree[now.to] = u;
				sum[now.to] = i;
				q[++tail] = now.to;
			}
		}
	}
	return ;
}
void findmincostblockingflow()
{
	ff = 0;
	while(1)
	{
		//cout << ff << ' ';
		SPFA();
		//cout << dist[t] << ' ' << ff << "---------------------\n";
		if(dist[t] == INF) break;
		ff = 1;
		tt = t;
		minn = INF;
		while(tt != s)
		{
			minn = men(minn,stepG[pree[tt]][sum[tt]].v);
			tt = pree[tt];
		}
		tt = t;
		while(tt != s)
		{
			stepG[pree[tt]][sum[tt]].v -= minn;
			tt = pree[tt];
		}
	}
}
void update()
{
	for(int i = 1;i <= n;i++)
	{
		for(int j = 0;j < stepG[i].size();j++)
		{
			G[i][indexx[i][stepg[i][j].to]].v -= (stepg[i][j].v - stepG[i][j].v);
			ans += (stepg[i][j].v - stepG[i][j].v) * G[i][indexx[i][stepg[i][j].to]].costt;
			//cout << i << ' ' << stepg[i][j].to << ' ' << (stepg[i][j].v - stepG[i][j].v) << '\n';
			//cout << i << ' ' << G[i][j].to << ' ' << G[i][j].v << '\n';
			G[stepg[i][j].to][indexx[stepg[i][j].to][i]].v += (stepg[i][j].v - stepG[i][j].v);
		}
	}
}
void dinitz()
{
	while(1)
	{
		makestepgraph();
		findmincostblockingflow();
		if(!ff) break;
		update();
		//cout << ans << '\n';
	}
	return ;
}
void output()
{
	for(int i = 0;i < G[s].size();i++)
	{
		//cout << G[s][i].to << ' ' << g[s][i].v << ' ' << G[s][i].v << '\n';
		maxflow += (g[s][i].v - G[s][i].v);
	}
	cout << maxflow << ' ' << ans << '\n';
}
signed main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	input();
	dinitz();
	output();
	return 0;
}
2024/7/23 19:25
加载中...