1 条题解
-
1sssSSSay LV 10 @ 2017-10-23 16:56:56
0/1分数规划
二分答案 + 费用流#include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #define INF 1e9 + 7 #define eps 1e-7 using namespace std; const int Maxn = 205; const int N = 20100; struct node { double val; short cap, to, next; } e[N]; short n, a[Maxn][Maxn], b[Maxn][Maxn], tot = 1, h[Maxn], S, T, s, pre[Maxn], cur[Maxn]; double dis[Maxn]; bool vis[Maxn]; inline char NC(void) { static char buf[100000], *p1 = buf, *p2 = buf; if (p1 == p2) { p2 = (p1 = buf) + fread(buf, 1, 100000, stdin); if (p1 == p2) return EOF; } return *p1++; } inline int read() { static char c; c = NC(); int x; static int minus; minus = 1; for (x = 0; !(c >= '0' && c <= '9'); c = NC()) if(c == '-') minus = -1; for (; c >= '0' && c <= '9'; x = x * 10 + c - '0', c = NC()); x *= minus; return x; } inline void Link(int u, int v, int c, double w) { e[++tot].to = v; e[tot].next = h[u]; e[tot].cap = c; e[tot].val = w; h[u] = tot; } inline void Add(int u, int v, int c, double w) { Link(u, v, c, w); Link(v, u, 0, -w); } short Dfs(short u, short Min) { if(u == T) return Min; int w, used = 0; vis[u] = 1; for(short i = h[u]; i; i = e[i].next){ if(!vis[e[i].to] && e[i].cap && dis[e[i].to] + e[i].val == dis[u]){ w = Dfs(e[i].to, min(e[i].cap, Min)); e[i].cap -= w; e[i ^ 1].cap += w; used += w; if(used == Min)return Min; } } if(used == 0) vis[u] = 1; return used; } inline bool Bfs() { double Min = 1e100; for(short i = S; i <= T; ++i) if(vis[i]) for(short j = h[i]; j; j = e[j].next) if(!vis[e[j].to] && e[j].cap){ Min = min(Min, dis[e[j].to] + e[j].val - dis[i]); } if(Min == 1e100) return 0; for(short i = S; i <= T; ++i) if(vis[i]) {dis[i] += Min; vis[i] = 0;} return 1; } double Check1(float c) { memset(dis, 0 ,sizeof(dis)); for(register short i = 2; i <= tot; ++i) { if(e[i].to >= n + 1 && e[i].to <= n + n && e[i ^ 1].to >= 1 && e[i ^ 1].to <= n) { int u = e[i ^ 1].to, v = e[i].to - n; e[i].cap = 1; e[i].val = c * (double)b[u][v] - (double)a[u][v]; e[i ^ 1].cap = 0; e[i ^ 1].val = -e[i].val; } if(e[i ^ 1].to == S) e[i].cap = 1, e[i ^ 1].cap = 0; if(e[i].to == T) e[i].cap = 1, e[i ^ 1].cap = 0; } double res = 0; int s = 0; do{ double temp = 0; while(temp = Dfs(S, 32000)){ memset(vis, 0, sizeof(vis)); res += temp * dis[S]; } } while(Bfs()); double A = 0, B = 0; for(int i = 2; i <= tot; ++i) { int u = e[i ^ 1].to, v = e[i].to; if(u >= 1 && u <= n && v >= n + 1 && v <= n + n && e[i].cap == 0) { A += a[u][v - n]; B += b[u][v - n]; } } return A / B; } int main() { // freopen("ball.in", "r", stdin); // freopen("ball.out", "w", stdout); n = read(); T = n + n + 1; for(int i = 1; i <= n; ++i) { for(int j = 1; j <= n; ++j) a[i][j] = read(); } for(int i = 1; i <= n; ++i) { for(int j = 1; j <= n; ++j) b[i][j] = read(); } for(int i = 1; i <= n; ++i) { Add(S, i, 1, 0); Add(i + n, T, 1, 0); for(int j = 1; j <= n; ++j) Add(i, j + n, 1, 0); } double l = 0, r; while(true) { r = Check1(l); if(r - l < eps) break; l = r; } printf("%.6lf\n", r); return 0; }
- 1
信息
- ID
- 2016
- 难度
- 5
- 分类
- (无)
- 标签
- 递交数
- 76
- 已通过
- 27
- 通过率
- 36%
- 被复制
- 2
- 上传者