# [BZOJ1070][SCOI2007]修车

[BZOJ1070][SCOI2007]修车

2 2
3 2
1 4

1.50

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <cstdlib>
using namespace std;

int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}

#define maxn 610
#define maxm 666010
#define oo 2147483647
#define LL long long

struct Edge { int from, to, flow, cost; } ;
struct ZKW {
int n, m, s, t, head[maxn], next[maxm];
LL ans, cost;
Edge es[maxm];
bool inq[maxn];
int d[maxn];
bool vis[maxn];
void init() {
return ;
}
void AddEdge(int a, int b, int c, int d) {
es[m] = (Edge){ a, b, c, d }; next[m] = head[a]; head[a] = m++;
es[m] = (Edge){ b, a, 0, -d }; next[m] = head[b]; head[b] = m++;
return ;
}
bool BFS() {
for(int i = 1; i <= n; i++) d[i] = oo;
memset(inq, 0, sizeof(inq));
d[t] = 0;
deque <int> Q; Q.push_front(t); inq[t] = 1;
while(!Q.empty()) {
int u = Q.front(); Q.pop_front(); inq[u] = 0;
for(int i = head[u]; i != -1; i = next[i]) {
Edge& e = es[i^1];
if(e.flow && d[e.from] > d[u] + e.cost) {
d[e.from] = d[u] + e.cost;
if(!inq[e.from]) {
inq[e.from] = 1;
if(Q.empty() || d[e.from] <= d[Q.front()]) Q.push_front(e.from);
else Q.push_back(e.from);
}
}
}
}
if(d[s] == oo) return 0;
for(int i = 0; i < m; i++) es[i].cost += d[es[i].to] - d[es[i].from];
cost += d[s];
return 1;
}
int DFS(int u, int a) {
if(u == t || !a){ ans += cost * a; return a; }
vis[u] = 1;
int flow = 0, f;
for(int i = head[u]; i != -1; i = next[i]) {
Edge& e = es[i];
if(!vis[e.to] && e.flow && !e.cost && (f = DFS(e.to, min(a, e.flow)))) {
flow += f; a -= f;
e.flow -= f; es[i^1].flow += f;
if(!a) return flow;
}
}
return flow;
}
void MinCost() {
s = n - 1; t = n;
ans = cost = 0;
while(BFS())
do
memset(vis, 0, sizeof(vis));
while(DFS(s, oo));
return ;
}
} sol;

int main() {
sol.init();
sol.n = n + n * m + 2; int s = sol.n - 1, t = sol.n;
for(int i = 1; i <= n; i++) sol.AddEdge(s, i, 1, 0);
for(int car = 1; car <= n; car++)
for(int eng = 1; eng <= m; eng++) {
for(int i = 0; i < n; i++) sol.AddEdge(car, n+m*i+eng, 1, tmp*(i+1));
}
for(int eng = 1; eng <= m; eng++)
for(int i = 0; i < n; i++) sol.AddEdge(n+m*i+eng, t, 1, 0);

sol.MinCost();
printf("%.2lf\n", sol.ans / (double)n);

return 0;
}


posted @ 2016-08-01 09:11  xjr01  阅读(273)  评论(0编辑  收藏  举报