博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P4307 球队收益
阅读量:6568 次
发布时间:2019-06-24

本文共 3518 字,大约阅读时间需要 11 分钟。

题意:有n个球队,m场比赛。

每个球队都已经有些胜负场次了。

每个球队的收益为Ci * wini2 - Di * losei2

求最小可能总收益。

解:

先看出一个模型:用一流量代表一个胜场,每场比赛向两支队伍连边。

然后我们发现这个费用是跟流量的平方有关的,How to do?

先观察一波:1 4 9 16 25

差分:1 3 5 7 9

然后我们就发现:如果把下面差分建成边的费用,限流为1,恰好就是收益了。

至此茅塞顿开。

首先假设所有的队伍都输了,然后每场选出一名胜者,C(2win + 1) - D(2lose - 1)为费用。

最小费用最大流即可。

1 #include 
2 #include
3 #include
4 #include
5 6 const int N = 6050, M = 1000010; 7 const int INF = 0x3f3f3f3f; 8 9 struct Edge { 10 int nex, v; 11 int c, len; 12 }edge[M << 1]; int top = 1; 13 14 int e[N], vis[N], pre[N]; 15 int d[N], flow[N]; 16 std::queue
Q; 17 int A[N], B[N], C[N], D[N], win[N], los[N], X[N], Y[N]; 18 19 inline void add(int x, int y, int z, int w) { 20 //printf("add : %d %d \n", x, y); 21 top++; 22 edge[top].v = y; 23 edge[top].c = z; 24 edge[top].len = w; 25 edge[top].nex = e[x]; 26 e[x] = top; 27 28 top++; 29 edge[top].v = x; 30 edge[top].c = 0; 31 edge[top].len = -w; 32 edge[top].nex = e[y]; 33 e[y] = top; 34 return; 35 } 36 37 inline bool SPFA(int s, int t) { 38 memset(d, 0x3f, sizeof(d)); 39 d[s] = 0; 40 flow[s] = INF; 41 vis[s] = 1; 42 Q.push(s); 43 while(!Q.empty()) { 44 int x = Q.front(); 45 Q.pop(); 46 vis[x] = 0; 47 //printf("x = %d d = %d\n", x, d[x]); 48 for(int i = e[x]; i; i = edge[i].nex) { 49 int y = edge[i].v; 50 if(edge[i].c && d[y] > d[x] + edge[i].len) { 51 d[y] = d[x] + edge[i].len; 52 pre[y] = i; 53 flow[y] = std::min(flow[x], edge[i].c); 54 if(!vis[y]) { 55 vis[y] = 1; 56 Q.push(y); 57 } 58 } 59 } 60 } 61 return d[t] < INF; 62 } 63 64 inline void update(int s, int t) { 65 int temp = flow[t]; 66 while(t != s) { 67 int i = pre[t]; 68 edge[i].c -= temp; 69 edge[i ^ 1].c += temp; 70 t = edge[i ^ 1].v; 71 } 72 return; 73 } 74 75 inline int solve(int s, int t, int &cost) { 76 int ans = 0; 77 cost = 0; 78 while(SPFA(s, t)) { 79 ans += flow[t]; 80 cost += flow[t] * d[t]; 81 update(s, t); 82 } 83 return ans; 84 } 85 86 int main() { 87 int n, m, s, t, sum = 0; 88 scanf("%d%d", &n, &m); 89 s = n + m + 1, t = m + n + 2; 90 for(int i = 1; i <= n; i++) { 91 scanf("%d%d%d%d", &win[i], &los[i], &C[i], &D[i]); 92 /*win[i] = A[i]; 93 los[i] = B[i];*/ 94 } 95 for(int i = 1; i <= m; i++) { 96 scanf("%d%d", &X[i], &Y[i]); 97 add(s, n + i, 1, 0); 98 add(n + i, X[i], 1, 0); 99 add(n + i, Y[i], 1, 0);100 los[X[i]]++;101 los[Y[i]]++;102 }103 for(int i = 1; i <= n; i++) {104 sum += C[i] * win[i] * win[i];105 sum += D[i] * los[i] * los[i];106 }107 for(int i = 1; i <= m; i++) {108 int x = X[i], y = Y[i];109 add(x, t, 1, C[x] * (2 * win[x] + 1) - D[x] * (2 * los[x] - 1));110 add(y, t, 1, C[y] * (2 * win[y] + 1) - D[y] * (2 * los[y] - 1));111 win[x]++;112 win[y]++;113 los[x]--;114 los[y]--;115 }116 117 int ans;118 solve(s, t, ans);119 printf("%d", ans + sum);120 return 0;121 }
AC代码

 

转载于:https://www.cnblogs.com/huyufeifei/p/10115857.html

你可能感兴趣的文章
JAVA SAX解析XML字符串实例
查看>>
python 网络爬虫学习笔记(一)
查看>>
gvim 实现自动全文排版
查看>>
云计算如何帮助直播行业发展
查看>>
基于Spring可扩展Schema提供自定义配置支持(spring配置文件中 配置标签支持)
查看>>
搞懂OpenLDAP
查看>>
数组名和数组名取地址的区别
查看>>
hive常用sql语句
查看>>
nc 命令传文件
查看>>
IIS中的sc-win32-status——Win32状态详细说明
查看>>
我的友情链接
查看>>
利用数据存储技术实现数据安全合理备份
查看>>
我的友情链接
查看>>
js_sqlite_ADODB.Connection
查看>>
hibernate开启二级缓存
查看>>
jsp自定义标签学习
查看>>
最短路径问题经典题目汇总
查看>>
iOS培训教程——设置默认语言
查看>>
zabbix登山路——简单监控_各项参数解析
查看>>
关于链表和指针变量的使用说明,可用于框架设计
查看>>