Network Wars

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

代码:

#include <algorithm>
#include <cstdio>
#include <iterator>
#include <limits>
#include <vector>
#include <string.h> const int N = 111;
const int M = 404;
const double EPS = 1e-3; typedef std::vector<int> VI; int signum(double x) {
return x > EPS ? 1 : (x < -EPS ? -1 : 0);
} template<int N, int M, class Flow>
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<Flow>::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<N,M<<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 ;
}

最新文章

  1. 关于printf错用格式化字符串导致double和long double输出错误的小随笔
  2. margin和padding的区别
  3. 基于命令行编译打包phonegap for android应用 分类: Android Phonegap 2015-05-10 10:33 73人阅读 评论(0) 收藏
  4. js原生
  5. Delphi 中同类型方法的说明
  6. Node.js的循环与异步问题
  7. centos6.5中 nginx-1.6.3 编译安装
  8. ubuntu16.04 搭建 Mysql服务器
  9. PYTHON压平嵌套列表
  10. emoji处理方法汇总
  11. TheSeventhWeekJavaText
  12. SSH 两个表全套增删改(运动员住宿管理)
  13. es6箭头函数讲解
  14. IOS学习——iphone X的适配
  15. Linux for sougou ping yin (http://pinyin.sogou.com/linux/help.php)
  16. MongoDB基本命令总结
  17. Linux常见问题汇总
  18. type的解释
  19. linux rpm 安装后 mysql 默认安装目录等信息
  20. Ansible Playbook 使用变量

热门文章

  1. 关于linux下的.a文件与 .so 文件
  2. easyui form.rest和clear 重置表单和清除表单数据区别
  3. html中保证中文能够正常显示
  4. SAS学习笔记之《SAS编程与数据挖掘商业案例》(3)变量操作、观测值操作、SAS数据集管理
  5. C#——接口的意义以及与抽象类的区别
  6. nginx-配置反向代理实例
  7. 2015.12.20-2015.12.25 大论文迭代 A
  8. FusionCharts 更新 chart data 数据
  9. CAD创建一个新的图形文件
  10. MHA的MySQL高可用方案实战