思路:

这题的结论得要看amber的论文,结论就是将求f(x)/b(x)最小转化为求min(f(x)-b(x)*λ),其中x为S集的解空间,f(x)为解的边权和,b(x)为解的边数,

λ=f(x)/b(x)。λ*为最优解,当且仅当(x属于S)∑min(f(x)-b(x)*λ)==0;故可以将原边权的权值改为w-λ;对λ进行二分枚举,找出答案。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 510
#define M 50010
#define inf 1e9
using namespace std;
const double eps=1e-;
struct Edge{
int to,next,from;
double val;
}edge[M];
int Index[N],d[N],gap[N],e,vi[N];
void addedge(int from,int to,double val)
{
edge[e].from=from;
edge[e].to=to;
edge[e].val=val;
edge[e].next=Index[from];
Index[from]=e++;
edge[e].from=to;
edge[e].to=from;
edge[e].val=val;
edge[e].next=Index[to];
Index[to]=e++;
}
int source,des,n,m;
void DFS(int u)
{
vi[u]=;
int i,v;
for(i=Index[u];i!=-;i=edge[i].next)
if(edge[i].val&&!vi[edge[i].to])
DFS(edge[i].to);
}
double dfs(int pos,double flow)
{
if(pos==des)
return flow;
int i,j,v,mind;
double val,c,lv;
mind=n-;//初始最小标号为n-1
lv=flow;
for(i=Index[pos];i!=-;i=edge[i].next)
{
v=edge[i].to;
val=edge[i].val;
if(val)
{
if(d[v]+==d[pos])
{
c=min(lv,val);//对于该点的最小可行流
c=dfs(v,c);
edge[i].val-=c;//更新剩余图
edge[i^].val+=c;
lv-=c;
if(d[source]>=n)return flow-lv;
if(lv==) break;
}
if(d[v]<mind)mind=d[v];//找出与pos相连的点的最小标号
}
}
if(lv==flow)//没有找到增广路劲,进行标号更新
{
--gap[d[pos]];
if(!gap[d[pos]])
d[source]=n;
d[pos]=mind+;
++gap[d[pos]];
}
return flow-lv;
}
double sap(int st,int de)
{
source=st;
des=de;
memset(d,,sizeof(d));
memset(gap,,sizeof(gap));
gap[]=n;//初始标号为0的有n个.
double ans=;
while(d[st]<n)
{
ans+=dfs(st,inf);
//cout<<d[st]<<endl;
}
return ans;
}
void init()
{
e=;
memset(Index,-,sizeof(Index));
memset(vi,,sizeof(vi));
}
int main()
{
int i,j,a[N],b[N],w[N];
int lmin,rmax;
int ff=;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(ff)printf("\n");
ff=;
init();
lmin=inf;
rmax=;
for(i=;i<m;i++)
{
scanf("%d%d%d",a+i,b+i,w+i);
lmin=min(lmin,w[i]);
rmax=max(rmax,w[i]);
}
double l,r;
l=lmin,r=rmax;
double res=;
while(r-l>eps)
{
init();
double mid=(l+r)/;
res=;
for(i=;i<m;i++)
{
if(w[i]<=mid) res+=w[i]-mid;
else addedge(a[i],b[i],w[i]-mid);
}
res+=sap(,n);
if(res>)
l=mid;
else
r=mid;
}
init();
for(i=;i<m;i++)
{
if(w[i]<=r) continue;
addedge(a[i],b[i],w[i]-r);
}
sap(,n);
//cout<<r<<endl;
//cout<<vi[2]<<" "<<vi[3]<<" "<<vi[4]<<" "<<vi[5]<<endl;
DFS();
vector<int> ans;
for(i=;i<m;i++)
{
if((w[i]<=r)||(vi[a[i]]&&!vi[b[i]])||(!vi[a[i]]&&vi[b[i]]))
{
ans.push_back(i+);
//cout<<edge[i].from<<" "<<edge[i].to<<endl;
}
}
int temp=ans.size();
printf("%d\n",temp);
printf("%d",ans[]);
for(i=;i<temp;i++)
printf(" %d",ans[i]);
printf("\n");
}
return ;
}

zoj 2676 网络流+01分数规划的更多相关文章

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

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

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

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

  3. ZOJ - 2676 01分数规划 浮点ISAP

    题意:求最小割集\(C\),使得\(\frac{\sum_{i∈C} cost_i}{|C|}\)最小 模型就是01分数规划\(\frac{\sum_{i=1}^{m}cost_i*x}{\sum_{ ...

  4. zoj 2676 二分+ISAP模板求实型参数的最小割(0-1分数规划问题)(可做ISAP模板)

    /* 参考博文:http://www.cnblogs.com/ylfdrib/archive/2010/09/01/1814478.html 以下题解为转载代码自己写的: zoj2676 胡伯涛论文& ...

  5. BZOJ2285 [SDOI2011]保密 【01分数规划 + 网络流】

    题目 现在,保密成为一个很重要也很困难的问题.如果没有做好,后果是严重的.比如,有个人没有自己去修电脑,又没有拆硬盘,后来的事大家都知道了. 当然,对保密最需求的当然是军方,其次才是像那个人.为了应付 ...

  6. 【转】[Algorithm]01分数规划

    因为搜索关于CFRound277.5E题的题解时发现了这篇文章,很多地方都有值得借鉴的东西,因此转了过来 原文:http://www.cnblogs.com/perseawe/archive/2012 ...

  7. [转]01分数规划算法 ACM 二分 Dinkelbach 最优比率生成树 最优比率环

    01分数规划 前置技能 二分思想最短路算法一些数学脑细胞? 问题模型1 基本01分数规划问题 给定nn个二元组(valuei,costi)(valuei,costi),valueivaluei是选择此 ...

  8. bzoj 4501: 旅行 01分数规划+概率期望dp

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=4501 题解: 首先我们不考虑可以删除边的情况下,如何计算期望边数. 然后我们发现这是个有 ...

  9. POJ3621Sightseeing Cows[01分数规划 spfa(dfs)负环 ]

    Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9703   Accepted: 3299 ...

随机推荐

  1. C++常用容器

    vector 顺序容器,和数组类似,可从尾部快速的插入和删除,可随机访问. vector的常用成员函数: #include<vector> std::vector<type> ...

  2. Lua学习笔记(三):函数和闭包

    函数 lua的函数以function关键字开始,后跟函数名称和参数,最后以end结束,我们看一个简单的函数定义: function foo() --do something end function ...

  3. 利用 SQL Monitor 查看语句运行状态步骤

    利用 SQL Monitor 查看语句运行状态步骤 1.确定语句被 SQL Monitor 监控 SQL> SELECT * FROM GV$SQL_MONITOR WHERE sql_id=' ...

  4. freeRadius 基础配置及测试

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...

  5. PostgreSQL的 initdb 源代码分析之十五

    继续分析: if (pwprompt || pwfilename) get_set_pwd(); 由于我启动initdb的时候,没有设置口令相关的选项,故此略过. 接下来: setup_depend( ...

  6. Android如何判断一个应用在运行

    在一个应用中,或一个Service .Receiver中有时候需要判断一个应用是否正在运行,以便进行一些相关的处理,这个时候我们需要得到一个ActivityManager,这个Manager顾名思意就 ...

  7. 【转】python的小知识

    1. 如何反序访问一个序列(how do I iterate over a sequence in reverse order) 如果序列是list,则使用list.reverse()即可将序列反序. ...

  8. hadoop数据[Hadoop] 实际应用场景之 - 阿里

    上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助.明天在这里和大家一起学习一下hadoop数据 Hadoop在淘宝和支付宝的应用从09年开始,用于对海量数据的离线处置,例如对日志的分析,也涉及内 ...

  9. android 手电筒的实现

    android手机用闪光灯做成手电筒的应用非常多,可是有的不能用. 后来发现是除了把 camera device的 flashmode设置成torch外还要打开预览: 以下是代码: MainActiv ...

  10. Python写的东西在CMD下打印中文

    以前遇到的问题是在IDLE中可以print出中文,在cmd却是乱码. 后来想明白,IDLE中默认编码是unicode,而cmd中是ANSI,即cp963,即GBK 所以这样就能输出中文了: s = “ ...