http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1676

对顶点i,j,起点s=1,终点t=n,可以认为题意要求一组01矩阵use[i][j],使得aveCost=sigma(use[i][j]*cost[i][j])/sigma(use[i][j])最小,且{(i,j)|use[i][j]==1}是图的S-T割

定义F(e)=min(sigma(use[i][j]*(cost[i][j]-a))),明显,F(e)是目标式的变形,且当F(e)=0时,a就是aveCost,以cost[i][j]-a为容量建图,那么此时F(e)就是最小割容量.

二分确定最小割也即最大流为0时的a值,当流量恰好为0时取值最优,否则,若流量大于0不是最优,流量小于0不满足题意

注意:当确定a值时,cost[i][j]-a会导致负容量边,这些边可以使F(e)更小,所以直接加上即可

 #include <cstdio>
#include <cstring>
#include<algorithm>
#include <queue>
#include <cmath>
using namespace std;
const int maxn=;
const int maxm=;
const int inf=0x7fffffff;
const double eps=1e-;
int n,m;
int G[maxn][maxn];
int e[maxn][maxn];
int len[maxn];
int num[maxn];
int ind[maxn][maxn];
double c[maxn][maxn];
double f[maxn][maxn];
int ans[maxm];
int alen;
bool pars[maxn];
int dis[maxn];
int gap[maxn]; void addedge(int f,int t){
G[f][len[f]++]=t;
G[t][len[t]++]=f;
}
double build(double lamda){
double flow=;
memset(len,,sizeof(len));
for(int i=;i<=n;i++){
for(int j=;j<num[i];j++){
int to=e[i][j];
if(i<to){
f[i][to]=c[i][to]-lamda;
f[to][i]=c[i][to]-lamda;
if(f[i][to]<){flow+=f[i][to];}
else{
addedge(i,to);
}
}
}
}
memset(dis,,sizeof(dis));
memset(gap,,sizeof(gap));
gap[]=n;
return flow;
} double dfs(int s,double flow){
if(s==n)return flow;
int mindis=n-;
double tflow=flow,sub;
for(int i=;i<len[s];i++){
int to=G[s][i];
if(f[s][to]>eps){
if(dis[to]+==dis[s]){
sub=dfs(to,min(tflow,f[s][to]));
f[s][to]-=sub;
f[to][s]+=sub;
tflow-=sub;
if(dis[]>=n)return flow-tflow;
if(tflow<eps)break;
}
mindis=min(mindis,dis[to]);
}
}
if(flow-tflow<eps){
--gap[dis[s]];
if(gap[dis[s]]==)dis[]=n;
else {
dis[s]=mindis+;
++gap[dis[s]];
}
}
return flow-tflow;
} double maxflow(double lamda){
double flow=build(lamda);
while(dis[]<n){
flow+=dfs(,inf);
}
return flow;
} double binarysearch(double s,double e){
if(s+eps>e){return s;}
double mid=(s+e)/;
double flow=maxflow(mid);
if(fabs(flow)<eps)return mid;
else if(flow<-eps){
return binarysearch(s,mid);
}
else {
return binarysearch(mid,e);
}
} void fnd(double a){
memset(pars,,sizeof(pars));
queue<int >que;
que.push();
pars[]=true;
while(!que.empty()){
int s=que.front();que.pop();
for(int i=;i<len[s];i++){
int to=G[s][i];
if(!pars[to]&&f[s][to]>eps){
pars[to]=true;que.push(to);
}
}
}
alen=;
for(int i=;i<=n;i++){
if(pars[i]){
for(int j=;j<num[i];j++){
int to=e[i][j];
if(!pars[to]){
ans[alen++]=ind[i][to];
}
else if(i<to&&c[i][to]+eps<a){
ans[alen++]=ind[i][to];
}
}
}
else {
for(int j=;j<num[i];j++){
int to=e[i][j];
if(i<to&&!pars[to]&&c[i][to]+eps<a){
ans[alen++]=ind[i][to];
}
}
}
}
sort(ans,ans+alen);
} int main(){
bool first=true;
while(scanf("%d%d",&n,&m)==){
if(!first)puts("");
else first=false;
memset(num,,sizeof(num));
int maxc=,minc=1e7+;
for(int i=;i<=m;i++){
int f,t,cost;
scanf("%d%d%d",&f,&t,&cost);
e[f][num[f]++]=t;
e[t][num[t]++]=f;
c[f][t]=c[t][f]=cost;
ind[f][t]= ind[t][f]=i;
maxc=max(maxc,cost);
minc=min(minc,cost);
}
double a=binarysearch(,maxc+);
fnd(a);
printf("%d\n",alen);
for(int i=;i<alen;i++)printf("%d%c",ans[i],i==alen-?'\n':' ');
}
return ;
}

HDU 2676 Network Wars 01分数规划,最小割 难度:4的更多相关文章

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

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

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

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

  3. bzoj 3232 圈地游戏 —— 01分数规划+最小割建图(最大权闭合子图)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3232 心烦意乱的时候调这道题真是...越调越气,就这样过了一晚上... 今天再认真看看,找出 ...

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

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

  5. zoj2676 Network Wars(0-1分数规划,最大流模板)

    Network Wars 07年胡伯涛的论文上的题:http://wenku.baidu.com/view/87ecda38376baf1ffc4fad25.html 代码: #include < ...

  6. 【BZOJ3232】圈地游戏 分数规划+最小割

    [BZOJ3232]圈地游戏 Description DZY家的后院有一块地,由N行M列的方格组成,格子内种的菜有一定的价值,并且每一条单位长度的格线有一定的费用. DZY喜欢在地里散步.他总是从任意 ...

  7. bzoj 3232: 圈地游戏【分数规划+最小割】

    数组开小导致TTTTTLE-- 是分数规划,设sm为所有格子价值和,二分出mid之后,用最小割来判断,也就是判断sm-dinic()>=0 这个最小割比较像最大权闭合子图,建图是s像所有点连流量 ...

  8. 【洛谷P2494】 [SDOI2011]保密(分数规划+最小割)

    洛谷 题意: 题意好绕好绕...不想写了. 思路: 首先类似于分数规划做法,二分答案得到到每个点的最小危险度. 然后就是在一个二分图中,两边撤掉最少的点(相应代价为上面算出的危险度)及相应边,使得中间 ...

  9. 洛谷2494 [SDOI2011]保密 (分数规划+最小割)

    自闭一早上 分数规划竟然还能被卡精度 首先假设我们已经知道了到每个出入口的时间(代价) 那我们应该怎么算最小的和呢? 一个比较巧妙的想法是,由于题目规定的是二分图. 我们不妨通过最小割的形式. 表示这 ...

随机推荐

  1. web设计经验<四>设计师必备的20条设计黄金法则

    编者按:以下内容摘自<美国视觉设计学院之完形设计>,新手可以多看这些法则,并运用到你的设计过程中,防止自己做出甲方式审美的作品. 一.必须有一个概念 设计从创意开始.这可能是非常不确定的— ...

  2. android MTK驱动背光唤醒流程

    在标准的android驱动中,睡眠唤醒流程非常清晰,能够较方便的更改lcd唤醒时间和led背光的点亮时间,但是也很容易出现问题,比如说闪屏,唤醒慢! 出现闪屏有两个原因 1. 开背光时间在唤醒lcd前 ...

  3. Oracle一列的多行数据拼成一行显示字符

    Oracle一列的多行数据拼成一行显示字符   oracle 提供了两个函数WMSYS.WM_CONCAT 和 ListAgg函数.    www.2cto.com   先介绍:WMSYS.WM_CO ...

  4. HBase分享会议笔记

    今天参加了一个关于HBase的分享,有一些内容是之前的知识的补充. 之前关于Hadoop家族,包括HBase的内容,可以参考:http://www.cnblogs.com/charlesblc/p/6 ...

  5. hdu1907(anti-sg入门)

    改变了下规则,现在变成了最后拿的人输. 如果对于单纯的nim的话,只需要判断每堆都是1个石子的特殊情况. 因为如果存在有大于1个石子的堆话,类似于nim的取法,处于必胜状态的一方只需要在 对方取完后只 ...

  6. Virtualbox虚拟机安装CentOS6.5图文详细教程(zhuan)

    http://www.2cto.com/os/201407/318477.html ************************************************* 什么是Virtu ...

  7. linux 安装 easygui

    如果遇到问题也查找不到资料时,可以认真阅读安装文件下的README说明,或许可以得到帮助. 本次环境为redhat 6.4.python2.7.9 linux 图形化显示需要安装一些依赖包,比如lib ...

  8. MyBatis学习笔记(三) 关联关系

    首先给大家推荐几个网页: http://blog.csdn.net/isea533/article/category/2092001 没事看看 - MyBatis工具:www.mybatis.tk h ...

  9. SqlServer_Sql防止注入

    注入式攻击的详细解释SQL下面我们将以一个简单的用户登陆为例,结合代码详细解释一下SQL注入式攻击,与及他的防范措施.对于一个简单的用户登陆可能的代码如下:try{ string strUserNam ...

  10. SQL 比较时间大小

    比较字符串类型的时间大小 数据库中的时间是varchar类型的,MySql使用CURDATE()来获取当前日期,SqlServer通过GETDATE()来获取当前日期 1. 直接使用字符串来比较 注意 ...