博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
zoj2676 Network Wars(0-1分数规划,最大流模板)
阅读量:6577 次
发布时间:2019-06-24

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

Network Wars

07年胡伯涛的论文上的题:http://wenku.baidu.com/view/87ecda38376baf1ffc4fad25.html

代码:

#include 
#include
#include
#include
#include
#include
const int N = 111;const int M = 404;const double EPS = 1e-3;typedef std::vector
VI;int signum(double x) { return x > EPS ? 1 : (x < -EPS ? -1 : 0);}template
struct Dinic { int n, e, first[N], cur[N], next[M], to[M], id[M], s, t; int pre[N], level[N], q[N], sign; Flow cap[M], flow; void add(int u, int v, Flow w, int i) { to[e] = v; cap[e] = w; id[e] = i; next[e] = first[u]; first[u] = e++; } bool bfs(int s, int t) { std::fill(level+1, level + n + 1, -1); sign = t; level[t] = 0; int head = 0, tail = 0; q[tail++] = t; while (head != tail && level[s] == -1) { int u = q[head++]; for (int it = first[u]; it != -1; it = next[it]) { if (cap[it ^ 1] > 0 && level[to[it]] == -1) { level[to[it]] = level[u] + 1; q[tail++] = to[it]; } } } return level[s] != -1; } void push() { Flow delta = std::numeric_limits
::max(); int u, p; for (u = t; u != s; u = to[p ^ 1]) { p = pre[u]; delta = std::min(delta, cap[p]); } for (u = t; u != s; u = to[p ^ 1]) { p = pre[u]; cap[p] -= delta; if (!cap[p]) { sign = to[p ^ 1]; } cap[p ^ 1] += delta; } flow += delta; } void dfs(int u) { if (u == t) { push(); } else { for (int & it = cur[u]; it != -1; it = next[it]) { if (cap[it] > 0 && level[u] == level[to[it]] + 1) { pre[to[it]] = it; dfs(to[it]); if (level[sign] > level[u]) { return; } sign = t; } } level[u] = -1; } } void init(int _n, int _s, int _t) { n = _n, s = _s, t = _t; std::fill(first + 1 , first + n + 1 , -1); e = 0; } Flow solve() { flow = 0; while (bfs(s, t)) { for (int i = 1; i <= n; ++i) { cur[i] = first[i]; } dfs(s); } return flow; }};Dinic
<<1,double> AC ;int left[M] , right[M] , w[M] ;int n , m , mark[M] ;double judge ( double key ) { double sum = 0 ; memset ( mark , 0 , sizeof ( mark ) ) ; AC.init ( n , 1 , n ) ; for ( int i = 1 ; i <= m ; i ++ ) if ( w[i] <= key ) { sum += w[i] - key ; mark[i] = 1 ; } else { AC.add ( left[i] , right[i] , w[i] - key , i ) ; AC.add ( right[i] , left[i] , w[i] - key , i ) ; } double add = AC.solve () ; sum += add ; return sum ;}void solve () { double l = 0 , r = (double) m * 1e7 ; while ( signum (r-l) > 0 ) { double mid = ( l + r ) / 2.0 ; double k = judge ( mid ) ; if ( signum ( k ) >= 0 ) l = mid ; else r = mid ; } AC.bfs ( 1 , n ) ; for ( int i = 0 ; i < AC.e ; i ++ ) { int u = AC.to[i^1] , v = AC.to[i] ; if ( AC.level[u] == -1 && AC.level[v] != -1 ) mark[AC.id[i]] = 1 ; } int ans = 0 ; for ( int i = 1 ; i <= m ; i ++ ) if ( mark[i] ) ans ++ ; printf ( "%d\n" , ans ) ; for ( int i = 1 ; i <= m ; i ++ ) if ( mark[i] ) printf ( "%d " , i ) ; puts ( "" ) ;}int main () { // freopen("network.in", "r", stdin); // freopen("network.out", "w", stdout); int flag = 0 ; while ( scanf ( "%d%d" , &n , &m ) != EOF ) { for ( int i = 1 ; i <= m ; i ++ ) scanf ( "%d%d%d" , &left[i] , &right[i] , &w[i] ) ; if ( flag ) puts ( "" ) ; flag = 1 ; solve () ; } return 0 ;}

转载地址:http://qhyno.baihongyu.com/

你可能感兴趣的文章
gtp转换mbr
查看>>
js-数组常用方法、
查看>>
django rest framework
查看>>
登录注册界面
查看>>
SQL Server去重和判断是否为数字——OBJECT_ID的使用
查看>>
poj1985 求树的直径
查看>>
【R语言系列】read.table报错incomplete final line found by readTableHeader
查看>>
最全基础区间线段树模板
查看>>
Linux的时间同步
查看>>
ORACLE中通过SQL语句(alter table)来增加、删除、修改字段
查看>>
20170623_oracle备份和恢复_常见问题
查看>>
面向接口、对象、方面编程区别 -- 精简版
查看>>
安装win10 和win中的一些杂项问题
查看>>
嵌入式web服务器appweb和其他web服务器(goahead、boa...)
查看>>
知其然不知其所以然的悲惨后果【EF CodeFirst 实体关系两日游】
查看>>
jvm内存快照dump文件太大,怎么分析
查看>>
python类的反射使用方法
查看>>
js判断手机还是pc并跳转相关页面
查看>>
移动开发之浅析cocos2d-x的中文支持问题
查看>>
文本框默认文字内容消失显示效果
查看>>