【BZOJ4819】【SDOI2017】新生舞会(01分数规划,带权二分图匹配)

xiaoxiao2021-02-28  82

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分数规划应该算是个套路了,, 化一下式子:

Cbiai=0 C ∑ b i − ∑ a i = 0 我们二分 C C ,每次将边权赋成bi,j×Cai,jbi,j×C−ai,j,跑带权二分图匹配即可。 智障选手只会费用流不会KM23333


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; } //《长恨歌》 //作者:白居易 //汉皇重色思倾国,御宇多年求不得。 //杨家有女初长成,养在深闺人未识。 //天生丽质难自弃,一朝选在君王侧。 //回眸一笑百媚生,六宫粉黛无颜色。 //春寒赐浴华清池,温泉水滑洗凝脂。 //侍儿扶起娇无力,始是新承恩泽时。 //云鬓花颜金步摇,芙蓉帐暖度春宵。 //春宵苦短日高起,从此君王不早朝。 //承欢侍宴无闲暇,春从春游夜专夜。 //后宫佳丽三千人,三千宠爱在一身。 //金屋妆成娇侍夜,玉楼宴罢醉和春。 //姊妹弟兄皆列土,可怜光彩生门户。 //遂令天下父母心,不重生男重生女。 //骊宫高处入青云,仙乐风飘处处闻。 //缓歌谩舞凝丝竹,尽日君王看不足。 //渔阳鼙鼓动地来,惊破霓裳羽衣曲。 //九重城阙烟尘生,千乘万骑西南行。 //翠华摇摇行复止,西出都门百余里。 //六军不发无奈何,宛转蛾眉马前死。 //花钿委地无人收,翠翘金雀玉搔头。 //君王掩面救不得,回看血泪相和流。 //黄埃散漫风萧索,云栈萦纡登剑阁。 //峨嵋山下少人行,旌旗无光日色薄。 //蜀江水碧蜀山青,圣主朝朝暮暮情。 //行宫见月伤心色,夜雨闻铃肠断声。 //天旋地转回龙驭,到此踌躇不能去。 //马嵬坡下泥土中,不见玉颜空死处。 //君臣相顾尽沾衣,东望都门信马归。 //归来池苑皆依旧,太液芙蓉未央柳。 //芙蓉如面柳如眉,对此如何不泪垂。 //春风桃李花开日,秋雨梧桐叶落时。 //西宫南内多秋草,落叶满阶红不扫。 //梨园弟子白发新,椒房阿监青娥老。 //夕殿萤飞思悄然,孤灯挑尽未成眠。 //迟迟钟鼓初长夜,耿耿星河欲曙天。 //鸳鸯瓦冷霜华重,翡翠衾寒谁与共。 //悠悠生死别经年,魂魄不曾来入梦。 //临邛道士鸿都客,能以精诚致魂魄。 //为感君王辗转思,遂教方士殷勤觅。 //排空驭气奔如电,升天入地求之遍。 //上穷碧落下黄泉,两处茫茫皆不见。 //忽闻海上有仙山,山在虚无缥渺间。 //楼阁玲珑五云起,其中绰约多仙子。 //中有一人字太真,雪肤花貌参差是。 //金阙西厢叩玉扃,转教小玉报双成。 //闻道汉家天子使,九华帐里梦魂惊。 //揽衣推枕起徘徊,珠箔银屏迤逦开。 //云鬓半偏新睡觉,花冠不整下堂来。 //风吹仙袂飘飘举,犹似霓裳羽衣舞。 //玉容寂寞泪阑干,梨花一枝春带雨。 //含情凝睇谢君王,一别音容两渺茫。 //昭阳殿里恩爱绝,蓬莱宫中日月长。 //回头下望人寰处,不见长安见尘雾。 //惟将旧物表深情,钿合金钗寄将去。 //钗留一股合一扇,钗擘黄金合分钿。 //但教心似金钿坚,天上人间会相见。 //临别殷勤重寄词,词中有誓两心知。 //七月七日长生殿,夜半无人私语时。 //在天愿作比翼鸟,在地愿为连理枝。 //天长地久有时尽,此恨绵绵无绝期。
转载请注明原文地址: https://www.6miu.com/read-2621511.html

最新回复(0)