Description
学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴。有n个男生和n个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴。Cathy收集了这些同学之间的关系,比如两个人之前认识没计算得出a[i][j] ,表示第i个男生和第j个女生一起跳舞时他们的喜悦程度。Cathy还需要考虑两个人一起跳舞是否方便,比如身高体重差别会不会太大,计算得出 b[i][j],表示第i个男生和第j个女生一起跳舞时的不协调程度。当然,还需要考虑很多其他问题。Cathy想先用一个程序通过a[i][j]和b[i][j]求出一种方案,再手动对方案进行微调。Cathy找到你,希望你帮她写那个程序。一个方案中有n对舞伴,假设没对舞伴的喜悦程度分别是a’1,a’2,…,a’n,假设每对舞伴的不协调程度分别是b’1,b’2,…,b’n。令C=(a’1+a’2+…+a’n)/(b’1+b’2+…+b’n),Cathy希望C值最大。
Solution
01分数规划应该算是个套路了,,
化一下式子:
C∑bi−∑ai=0
C
∑
b
i
−
∑
a
i
=
0
我们二分 C C ,每次将边权赋成,跑带权二分图匹配即可。
Code
/************************************************
* Au: Hany01
* Date: Apr 9th, 2018
* Prob: [BZOJ4819][SDOI2017] 新生舞会
* Email: hany01@foxmail.com
************************************************/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define x first
#define y second
#define pb(a) push_back(a)
#define pf(a) push_front(a)
#define mp(a, b) make_pair(a, b)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) ((int)(a).size())
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define Mod (1000000007)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaia
template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
inline int read()
{
register int _, __; register char c_;
for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1;
for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
return _ * __;
}
const double eps = 1e-7;
inline int dcmp(double x) {
if (fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}
const int maxn = 105, maxv = 205, maxm = 20203;
int n, e, v[maxm], f[maxm], nex[maxm], beg[maxv], vis[maxv], tot, s, t, a[maxn][maxn], b[maxn][maxn];
double w[maxm], Cost, dis[maxv];
inline void add(int uu, int vv, int ff, double ww, int ty) {
v[++ e] = vv, f[e] = ff, w[e] = ww, nex[e] = beg[uu], beg[uu] = e;
if (ty) add(vv, uu, 0, -ww, 0);
}
inline bool BFS()
{
static queue<int> q;
For(i, 1, tot) dis[i] = INF, Set(vis, 0);
dis[s] = 0, vis[s] = 1, q.push(s);
while (!q.empty())
{
register int u = q.front(); q.pop(), vis[u] = 0;
for (register int i = beg[u]; i; i = nex[i])
if (f[i] && chkmin(dis[v[i]], dis[u] + w[i]))
if (!vis[v[i]]) vis[v[i]] = 1, q.push(v[i]);
}
return dcmp(dis[t] - INF);
}
int DFS(int u, int flow)
{
vis[u] = 1;
if (u == t) return flow;
register int res = flow, tmp;
for (register int i = beg[u]; i; i = nex[i])
if (!vis[v[i]] && f[i] && !dcmp(dis[v[i]] - dis[u] - w[i]))
{
tmp = DFS(v[i], min(f[i], res));
f[i] -= tmp, f[i ^ 1] += tmp, Cost += tmp * w[i];
if (!(res -= tmp)) return flow;
}
return flow - res;
}
inline double MCMF()
{
Cost = 0.;
while (BFS())
do Set(vis, 0), DFS(s, n); while (vis[t]);
return Cost;
}
inline double check(double c)
{
e = 1, Set(beg, 0);
For(i, 1, n) add(s, i, 1, 0, 1), add(i + n, t, 1, 0, 1);
For(i, 1, n) For(j, 1, n) add(i, j + n, 1, b[i][j] * c - a[i][j], 1);
return MCMF();
}
int main()
{
#ifdef hany01
File("bzoj4819");
#endif
static int Min = INF, Max = 0;
n = read();
For(i, 1, n) For(j, 1, n) chkmax(Max, a[i][j] = read());
For(i, 1, n) For(j, 1, n) chkmin(Min, b[i][j] = read());
static double l = 1e-4, r = Max * 1. / Min, mid;
s = n << 1 | 1, t = tot = (n + 1) << 1;
while (r - l >= eps) {
mid = (l + r) * .5;
if (check(mid) < 0) l = mid; else r = mid;
}
printf("%.6lf\n", l);
return 0;
}
//《长恨歌》
//作者:白居易
//汉皇重色思倾国,御宇多年求不得。
//杨家有女初长成,养在深闺人未识。
//天生丽质难自弃,一朝选在君王侧。
//回眸一笑百媚生,六宫粉黛无颜色。
//春寒赐浴华清池,温泉水滑洗凝脂。
//侍儿扶起娇无力,始是新承恩泽时。
//云鬓花颜金步摇,芙蓉帐暖度春宵。
//春宵苦短日高起,从此君王不早朝。
//承欢侍宴无闲暇,春从春游夜专夜。
//后宫佳丽三千人,三千宠爱在一身。
//金屋妆成娇侍夜,玉楼宴罢醉和春。
//姊妹弟兄皆列土,可怜光彩生门户。
//遂令天下父母心,不重生男重生女。
//骊宫高处入青云,仙乐风飘处处闻。
//缓歌谩舞凝丝竹,尽日君王看不足。
//渔阳鼙鼓动地来,惊破霓裳羽衣曲。
//九重城阙烟尘生,千乘万骑西南行。
//翠华摇摇行复止,西出都门百余里。
//六军不发无奈何,宛转蛾眉马前死。
//花钿委地无人收,翠翘金雀玉搔头。
//君王掩面救不得,回看血泪相和流。
//黄埃散漫风萧索,云栈萦纡登剑阁。
//峨嵋山下少人行,旌旗无光日色薄。
//蜀江水碧蜀山青,圣主朝朝暮暮情。
//行宫见月伤心色,夜雨闻铃肠断声。
//天旋地转回龙驭,到此踌躇不能去。
//马嵬坡下泥土中,不见玉颜空死处。
//君臣相顾尽沾衣,东望都门信马归。
//归来池苑皆依旧,太液芙蓉未央柳。
//芙蓉如面柳如眉,对此如何不泪垂。
//春风桃李花开日,秋雨梧桐叶落时。
//西宫南内多秋草,落叶满阶红不扫。
//梨园弟子白发新,椒房阿监青娥老。
//夕殿萤飞思悄然,孤灯挑尽未成眠。
//迟迟钟鼓初长夜,耿耿星河欲曙天。
//鸳鸯瓦冷霜华重,翡翠衾寒谁与共。
//悠悠生死别经年,魂魄不曾来入梦。
//临邛道士鸿都客,能以精诚致魂魄。
//为感君王辗转思,遂教方士殷勤觅。
//排空驭气奔如电,升天入地求之遍。
//上穷碧落下黄泉,两处茫茫皆不见。
//忽闻海上有仙山,山在虚无缥渺间。
//楼阁玲珑五云起,其中绰约多仙子。
//中有一人字太真,雪肤花貌参差是。
//金阙西厢叩玉扃,转教小玉报双成。
//闻道汉家天子使,九华帐里梦魂惊。
//揽衣推枕起徘徊,珠箔银屏迤逦开。
//云鬓半偏新睡觉,花冠不整下堂来。
//风吹仙袂飘飘举,犹似霓裳羽衣舞。
//玉容寂寞泪阑干,梨花一枝春带雨。
//含情凝睇谢君王,一别音容两渺茫。
//昭阳殿里恩爱绝,蓬莱宫中日月长。
//回头下望人寰处,不见长安见尘雾。
//惟将旧物表深情,钿合金钗寄将去。
//钗留一股合一扇,钗擘黄金合分钿。
//但教心似金钿坚,天上人间会相见。
//临别殷勤重寄词,词中有誓两心知。
//七月七日长生殿,夜半无人私语时。
//在天愿作比翼鸟,在地愿为连理枝。
//天长地久有时尽,此恨绵绵无绝期。