Network Wars


Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge

Network of Byteland consists of n servers, connected by m optical cables. Each cable connects two servers and can transmit data in both directions. Two servers of the network are especially important --- they are connected to global world network and president palace network respectively.

The server connected to the president palace network has number 1, and the server connected to the global world network has number n.

Recently the company Max Traffic has decided to take control over some cables so that it could see what data is transmitted by the president palace users. Of course they want to control such set of cables, that it is impossible to download any data from the global network to the president palace without transmitting it over at least one of the cables from the set.

To put its plans into practice the company needs to buy corresponding cables from their current owners. Each cable has some cost. Since the company's main business is not spying, but providing internet connection to home users, its management wants to make the operation a good investment. So it wants to buy such a set of cables, that cables mean cost} is minimal possible.

That is, if the company buys k cables of the total cost c, it wants to minimize the value of c/k.

Input

There are several test cases in the input. The first line of each case contains n and m (2 <= n <= 100 , 1 <= m <= 400 ). Next m lines describe cables~--- each cable is described with three integer numbers: servers it connects and the cost of the cable. Cost of each cable is positive and does not exceed107.

Any two servers are connected by at most one cable. No cable connects a server to itself. The network is guaranteed to be connected, it is possible to transmit data from any server to any other one.

There is an empty line between each cases.

Output

First output k --- the number of cables to buy. After that output the cables to buy themselves. Cables are numbered starting from one in order they are given in the input file. There should an empty line between each cases.

Example

Input Output
6 8
1 2 3
1 3 3
2 4 2
2 5 2
3 4 2
3 5 2
5 6 3
4 6 3
4
3 4 5 6
4 5
1 2 2
1 3 2
2 3 1
2 4 2
3 4 2
3
1 2 3

题目链接:ZOJ 2676

此题叫我们求$\Sigma w_{ei} \over |E|$的最小值,其中所有的边均在S-T的割中,可以发现当${\Sigma w_{ei} \over |E|}<r$时,存在$r'={\Sigma w_{ei} \over |E|}$作为更优的r,那我们写成$\Sigma w_{ei} - r*|E|<0$,存在一个左边的结果使得等式成立,即找到左边式子的最小值小于0即可,观察左边的式子,可以化简成$\Sigma (w_{ei}-r)<0$,然后边集e是一个割,又要求这个割集的最小值,那显然就是求s-t的最小割即可,先用二分求出最佳的比例,然后在最后剩下的那个残余网络中找出割集。

代码:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 110;
const int M = 410;
const double eps = 1e-6;
struct edge
{
int to, nxt;
double cap;
edge() {}
edge(int _to, int _nxt, double _cap): to(_to), nxt(_nxt), cap(_cap) {}
};
struct Node
{
int u, v;
double cap;
};
Node e[M];
edge E[M << 1];
int head[N], tot;
int d[N];
int use[M]; void init()
{
CLR(head, -1);
tot = 0;
CLR(use, 0);
}
inline void add(int s, int t, double cap)
{
E[tot] = edge(t, head[s], cap);
head[s] = tot++;
E[tot] = edge(s, head[t], cap);
head[t] = tot++;
}
int bfs(int s, int t)
{
CLR(d, -1);
d[s] = 0;
queue<int>Q;
Q.push(s);
while (!Q.empty())
{
int u = Q.front();
Q.pop();
for (int i = head[u]; ~i; i = E[i].nxt)
{
int v = E[i].to;
if (d[v] == -1 && E[i].cap > 0)
{
d[v] = d[u] + 1;
if (v == t)
return 1;
Q.push(v);
}
}
}
return ~d[t];
}
double dfs(int s, int t, double f)
{
if (s == t || !f)
return f;
double ret = 0;
for (int i = head[s]; ~i; i = E[i].nxt)
{
int v = E[i].to;
if (d[v] == d[s] + 1 && E[i].cap > 0)
{
double df = dfs(v, t, min(f, E[i].cap));
if (df > 0)
{
E[i].cap -= df;
E[i ^ 1].cap += df;
f -= df;
ret += df;
if (!f)
break;
}
}
}
if (!ret)
d[s] = -1;
return ret;
}
double dinic(int s, int t)
{
double ans = 0;
while (bfs(s, t))
ans += dfs(s, t, INF);
return ans;
}
double Mincut(int n, int m, double r)
{
int i;
init();
double ret = 0;
for (i = 1; i <= m; ++i)
{
if (e[i].cap < r)
{
ret += e[i].cap - r;
use[i] = 1;
}
else
add(e[i].u, e[i].v, e[i].cap - r);
}
return ret + dinic(1, n);
}
int main(void)
{
int n, m, i;
while (~scanf("%d%d", &n, &m))
{
for (i = 1; i <= m; ++i)
scanf("%d%d%lf", &e[i].u, &e[i].v, &e[i].cap);
double Rat = 0, L = 0, R = 400.0 / 3 * 1e7;
while (fabs(R - L) >= eps)
{
double mid = (L + R) / 2.0;
if (Mincut(n, m, mid) < 0)
{
R = mid;
Rat = mid;
}
else
L = mid;
}
vector<int>ans;
for (i = 1; i <= m; ++i)
{
if ((d[e[i].u]!=-1)^(d[e[i].v]!=-1))
use[i] = 1;
if (use[i])
ans.push_back(i);
}
int sz = ans.size();
printf("%d\n", sz);
for (i = 0; i < sz; ++i)
printf("%d%c", ans[i], " \n"[i == sz - 1]);
}
return 0;
}

ZOJ 2676 Network Wars(最优比例最小割)的更多相关文章

  1. zoj 2676 Network Wars 0-1分数规划+最小割

    题目详解出自 论文 Amber-最小割模型在信息学竞赛中的应用 题目大意: 给出一个带权无向图 G = (V,E), 每条边 e属于E都有一个权值We,求一个割边集C,使得该割边集的平均边权最小,即最 ...

  2. HDU 2676 Network Wars 01分数规划,最小割 难度:4

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1676 对顶点i,j,起点s=1,终点t=n,可以认为题意要求一组01矩阵use ...

  3. ZOJ 2676 Network Wars[01分数规划]

    ZOJ Problem Set - 2676 Network Wars Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special J ...

  4. ZOJ 2676 Network Wars ★(最小割算法介绍 && 01分数规划)

    [题意]给出一个带权无向图,求割集,且割集的平均边权最小. [分析] 先尝试着用更一般的形式重新叙述本问题.设向量w表示边的权值,令向量c=(1, 1, 1, --, 1)表示选边的代价,于是原问题等 ...

  5. ZOJ 2676 Network Wars(网络流+分数规划)

    传送门 题意:求无向图割集中平均边权最小的集合. 论文<最小割模型在信息学竞赛中的应用>原题. 分数规划.每一条边取上的代价为1. #include <bits/stdc++.h&g ...

  6. ZJU 2676 Network Wars

    Network Wars Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Original I ...

  7. BZOJ 3774: 最优选择( 最小割 )

    最小割...二分染色然后把颜色不同的点的源汇反过来..然后就可以做了. 某个点(x,y): S->Id(x,y)(回报), Id(x,y)->T(代价), Id(i,j)&& ...

  8. 【BZOJ3774】最优选择 最小割

    [BZOJ3774]最优选择 Description 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择 ...

  9. BZOJ 3774 最优选择 (最小割+二分图)

    题面传送门 题目大意:给你一个网格图,每个格子都有$a_{ij}$的代价和$b_{ij}$的回报,对于格子$ij$,想获得$b_{ij}$的回报,要么付出$a_{ij}$的代价,要么$ij$周围四联通 ...

随机推荐

  1. 博弈论经典算法(一)——对抗搜索与Alpha-Beta剪枝

    前言 在一些复杂的博弈论题目中,每一轮操作都可能有许多决策,于是就会形成一棵庞大的博弈树. 而有一些博弈论题没有什么规律,针对这样的问题,我们就需要用一些十分玄学的算法. 例如对抗搜索. 对抗搜索简介 ...

  2. SQL 值得记住的点

    概要 记录在学习过程中,遇到的不懂且需要掌握的知识点.主要基于 MySQL.   汇总      replace 函数      删除重复      取子串 substr      项连接      ...

  3. linux slab学习

    https://blog.csdn.net/bullbat/article/details/7194794 https://blog.csdn.net/qq_26626709/article/deta ...

  4. shiro学习记录(三)

    1.使用ehcache缓存权限数据 ehcache是专门缓存插件,可以缓存Java对象,提高系统性能. l ehcache提供的jar包: 第一步:在pom.xml文件中引入ehcache的依赖 &l ...

  5. 自建ssr(谷歌云免费试用一年)

    近期我一个朋友的VPN到期了,他也不想再去续费,同时发现谷歌云第一年申请时是免费的,所以他就自己搭建了一个自己专属的VPN 以下是他的搭建教程:  本教程难点在于申请免费试用资格 谷歌云+ssr搭建免 ...

  6. SummerVocation_Learning--java的线程死锁

    public class Test_DeadLock implements Runnable { ; static Object o1 = new Object(),o2 = new Object() ...

  7. 【Django】使用list对单个或者多个字段求values值

    使用list对values进行求值: 单个字段的输出结果: price_info=list(Book.objects.filter(auth_id='Yu').values('book_price') ...

  8. Freemaker基于word模板动态导出汇总整理

    Freemaker基于word模板动态导出汇总整理 一.使用的jar包: 二.Word模板动态导出的基本思路: 1.首先通过自己在word中创建好需要导出的word文本+表格的模板,模板中需要填写内容 ...

  9. JZOJ 4272. 【NOIP2015模拟10.28B组】序章-弗兰德的秘密

    272. [NOIP2015模拟10.28B组]序章-弗兰德的秘密 (File IO): input:frand.in output:frand.out Time Limits: 1000 ms  M ...

  10. 23.VUE学习之-列表的排序sort

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...