HDU 2676 Network Wars 01分数规划,最小割 难度:4
2015-03-16 13:18
309 查看
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)更小,所以直接加上即可
对顶点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=103; const int maxm=403; const int inf=0x7fffffff; const double eps=1e-5; 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=0; memset(len,0,sizeof(len)); for(int i=1;i<=n;i++){ for(int j=0;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]<0){flow+=f[i][to];} else{ addedge(i,to); } } } } memset(dis,0,sizeof(dis)); memset(gap,0,sizeof(gap)); gap[0]=n; return flow; } double dfs(int s,double flow){ if(s==n)return flow; int mindis=n-1; double tflow=flow,sub; for(int i=0;i<len[s];i++){ int to=G[s][i]; if(f[s][to]>eps){ if(dis[to]+1==dis[s]){ sub=dfs(to,min(tflow,f[s][to])); f[s][to]-=sub; f[to][s]+=sub; tflow-=sub; if(dis[1]>=n)return flow-tflow; if(tflow<eps)break; } mindis=min(mindis,dis[to]); } } if(flow-tflow<eps){ --gap[dis[s]]; if(gap[dis[s]]==0)dis[1]=n; else { dis[s]=mindis+1; ++gap[dis[s]]; } } return flow-tflow; } double maxflow(double lamda){ double flow=build(lamda); while(dis[1]<n){ flow+=dfs(1,inf); } return flow; } double binarysearch(double s,double e){ if(s+eps>e){return s;} double mid=(s+e)/2; 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,0,sizeof(pars)); queue<int >que; que.push(1); pars[1]=true; while(!que.empty()){ int s=que.front();que.pop(); for(int i=0;i<len[s];i++){ int to=G[s][i]; if(!pars[to]&&f[s][to]>eps){ pars[to]=true;que.push(to); } } } alen=0; for(int i=1;i<=n;i++){ if(pars[i]){ for(int j=0;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=0;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)==2){ if(!first)puts(""); else first=false; memset(num,0,sizeof(num)); int maxc=0,minc=1e7+1; for(int i=1;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(0,maxc+1); fnd(a); printf("%d\n",alen); for(int i=0;i<alen;i++)printf("%d%c",ans[i],i==alen-1?'\n':' '); } return 0; }
相关文章推荐
- 【ZOJ】2676 Network Wars 01分数规划+最小割
- zoj 2676 Network Wars(01分数规划+最小割)
- ZOJ 2676 Network Wars ★(最小割算法介绍 && 01分数规划)
- zoj 2676 Network Wars(最小割,01分数规划)
- ZOJ 2676 Network Wars(01分数规划-二分+最小割)
- ZOJ 2676 Network Wars ★(最小割算法介绍 && 01分数规划)
- ZOJ 2676 01分数规划 最小割
- 【ZOJ 2676】Network Wars 网络战争 网络流 01分数规划
- ZOJ 2676 Network Wars 最小割 分数规划
- zoj 2676 Network Wars(01分数规划+网络流)
- 【01分数规划】 ZOJ 2676 Network Wars
- ZOJ-2676-Network Wars(01分数规划+最小割)
- zoj 2676 Network Wars(01分数规划+最大流)
- zoj 2676 Network Wars 【0-1分数规划 + 最小割】 【吃一堑长一智】
- 【ZOJ2676】Network Wars 最小割+01分数规划
- [ZJU 2676]Network Wars(分数规划+最小割)
- zoj 2676 Network Wars 最小割+0-1分数规划
- ZOJ 2676 Network Wars[01分数规划]
- Network Wars-ZOJ2676最小割+01规划
- [省选前题目整理][BZOJ 1486][HNOI 2009]最小圈(01分数规划)