[SCOI2007]修车

spfa写挂一次

n,m看反一次

数组开小一次

233333333

丧心病狂的拆点技能get

顺便YM faebdc

Code:

#include <cstdio>
#include <cstring>
#include <queue>
#include <bitset>
using namespace std;
#define INF 0x7FFFFFFF
queue<int> Q;
#define N (60*9+60+2+233)
#define M (60*60*9+233)
bitset<N> vis;
struct E
{
	int to, f, next, op, c;
}G[M<<2];
int bh[61][10], point[N], S, T, cnt, D[N], n, m, pre[N], t[61][10], path[N], res;
inline void add(int u, int v, int f, int F, int c)
{
	cnt++, G[cnt] = (E){v, f, point[u], cnt+1, c}, point[u] = cnt;
	cnt++, G[cnt] = (E){u, F, point[v], cnt-1, -c}, point[v] = cnt;
}
inline bool spfa()
{
	int u, v;
	for (u = S;u <= T; ++u)
		D[u] = INF;
	while (!Q.empty())Q.pop();
	Q.push(S);
	vis.reset();
	D[S] = 0;
	pre[S] = -1;
	vis[S] = 1;
	while (!Q.empty())
	{
		u = Q.front(), Q.pop();
		for (int e = point[u];e;e = G[e].next)
		{
			v = G[e].to;
			if (G[e].f > 0 && D[u] + G[e].c < D[v])
			{
				D[v] = D[u] + G[e].c;
				pre[v] = u;
				path[v] = e;
				if (!vis[v])
					vis[v] = 1, Q.push(v);
			}
		}
		vis[u] = 0;
	}
	return D[T] != INF;
}
inline int argument()
{
	int i, delta = INF, flow = 0;
	for (i = T;pre[i] != -1;i = pre[i])
	{
		int e = path[i];
		delta = min(G[e].f, delta);
	}
	for (i = T;pre[i] != -1;i = pre[i])
	{
		int e = path[i];
		G[e].f -= delta;
		G[G[e].op].f += delta;
		flow += G[e].c * delta;
	}
	return flow;
}
int main()
{
	int i, j, k;
	scanf("%d %d", &m, &n);
	S = 0, T = n+n*m+1;
	for (i = 1;i <= n; ++i)
		for (j = 1;j <= m; ++j)
		{
			scanf("%d", &t[i][j]);
			bh[i][j] = (i-1)*m+j+n;
		}
	for (i = 1;i <= n; ++i)
	{
		add(S, i, 1, 0, 0);
		for (j = 1;j <= m; ++j)
			for (k = 1;k <= n; ++k)
				add(i, bh[k][j], 1, 0, t[i][j]*k);
	}
	for (i = 1;i <= n; ++i)
		for (j = 1;j <= m; ++j)
			add(bh[i][j], T, 1, 0, 0);
	while (spfa())res += argument();
	printf("%.2lf\n", (double)res/(double)n);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值