【ZOJ 2676】Network Wars 网络战争 网络流 01分数规划
来源:互联网 发布:西西软件下载 编辑:程序博客网 时间:2024/05/29 02:42
题目描述
Byteland的网络包含n个服务器,由m条光纤连接。每一条光纤连接两个服务器,数据能够在光纤上双向传输。网络中的两台服务器极其重要,他们分别连接了全球网络和总统府网络。
连接总统府网络的服务器编号1,连接全球网络的服务器编号n。最近,Max Traffic公司决定接管一些光纤,以便于他们了解总统府的用户传输的数据。当然他们想控制一些光纤,使得若想要下载从全球网络传输到总统府网络的任意数据,都必须经过这些光纤中的至少一条。
为了实施计划,公司需要从供货商那里购买相应的光纤。每一条光纤需要一定的花费。由于公司的主要业务不是间谍活动,而是想家庭用户提供网络连接,公司的管理层想要让这次行动成为绝佳的投资行为。因此公司想要购买满足上述要求的光纤,并且使得花费尽可能小。
也就是说,如果公司总共花费c购买了k条光纤,公司想要最小化c/k的值。
题目大意
给定一个无向图,选取一边集E(必须包含割),使得所选边集的边权平均值最小。(多组数据)
数据范围
(2 <= n <= 100 , 1 <= m <= 400 )
样例输入
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
解题思路
01分数规划,二分c/k的值,如果边权小于二分的值,则可以无脑选择,然后将没被选择的边加进网络流中(权值要减去c/k),来一次最小割。从源点DFS一下,输出两端点不在同一集合的边。
代码
#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <cmath>#define Maxn 23333//数组大小随缘开的233#define Maxe 23333using namespace std;inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}int n,m,S,T,N,cnt=0,x[Maxn],y[Maxn],v[Maxn],h[Maxn],GAP[Maxn],dis[Maxn];bool vis[Maxn],used[Maxn];struct node{int to,next,v,pair;}e[Maxe];void AddEdge(int X,int Y,int v,int pa){e[cnt]=(node){Y,h[X],v,pa};h[X]=cnt;}void AddEdge(int X,int Y,int v){AddEdge(X,Y,v,++cnt+1);AddEdge(Y,X,0,++cnt-1);}int SAP(int X,int Maxflow){ if(X==T)return Maxflow; int tmp=Maxflow; for(int p=h[X];p;p=e[p].next){ int y=e[p].to; int flow=min(tmp,e[p].v); if(flow&&dis[X]==dis[y]+1){ int ret=SAP(y,flow); tmp-=ret; e[p].v-=ret; e[e[p].pair].v+=ret; if(!tmp||dis[S]==n)return Maxflow-tmp; } } if(--GAP[dis[X]]==0)dis[S]=n; else GAP[++dis[X]]++; return Maxflow-tmp;}double SAP(){ memset(GAP,0,sizeof(GAP)); memset(dis,0,sizeof(dis)); GAP[0]=n; S=1,T=n; int Ans=0; while(dis[S]<n)Ans+=SAP(S,1<<30); return Ans;}bool Check(double k){ memset(e,0,sizeof(e)); memset(h,0,sizeof(h)); memset(used,0,sizeof(vis)); cnt=0; double ret=0.0; for(int i=1;i<=m;i++){ if(v[i]<=k){used[i]=1;ret+=v[i]-k;} else{AddEdge(x[i],y[i],v[i]-k);AddEdge(y[i],x[i],v[i]-k);}//这里的v[i]要减去K } return SAP()+ret>0;}void Init(){ for(int i=1;i<=m;i++)x[i]=Getint(),y[i]=Getint(),v[i]=Getint();}void Dfs(int x){ vis[x]=true; for(int p=h[x];p;p=e[p].next){ int y=e[p].to; if(!vis[y]&&e[p].v)Dfs(y); }}void Solve(){ double L=0,r=1e9; while(L+1e-8<r){//二分C/K的值,精读太低就会WA。。。 double mid=(L+r)/2; if(Check(mid))L=mid; else r=mid; } memset(vis,0,sizeof(vis)); Dfs(S); for(int i=1;i<=m;i++)if(vis[x[i]]!=vis[y[i]])used[i]=true; int Ans=0; for(int i=1;i<=m;i++)Ans+=used[i]; cout<<Ans<<"\n"; for(int i=1;i<=m;i++)if(used[i])cout<<i<<" "; cout<<"\n";}int main(){ while(scanf("%d%d",&n,&m)!=EOF){ Init(); Solve(); } return 0;}
求各位神犇给蒟蒻一点评论啊QAQ
0 0
- 【ZOJ 2676】Network Wars 网络战争 网络流 01分数规划
- zoj 2676 Network Wars(01分数规划+网络流)
- 【01分数规划】 ZOJ 2676 Network Wars
- zoj 2676 Network Wars(01分数规划+最大流)
- 【网络流】 ZOJ 2676 Network Wars
- zoj 2676 Network Wars(01分数规划+最小割)
- zoj 2676 Network Wars(最小割,01分数规划)
- 【ZOJ】2676 Network Wars 01分数规划+最小割
- ZOJ-2676-Network Wars(01分数规划+最小割)
- ZOJ 2676 Network Wars 最小割 分数规划
- ZOJ Problem Set - 2676 Network Wars(分数规划)
- zoj2676 Network Wars (01分数规划)
- zoj 2676 Network Wars 【0-1分数规划 + 最小割】 【吃一堑长一智】
- zoj 2676 Network Wars
- [ZJU 2676]Network Wars(分数规划+最小割)
- 【ZOJ2676】Network Wars 最小割+01分数规划
- zoj2676 Network Wars(0-1分数规划,最大流模板)
- cogs 2047. [ZOJ2676]网络战争 (最小割+01分数规划)
- 主流深度学习框架对比
- UVa-11388 GCD LCM
- 小雷的冰茶几——并查集
- 性能测试4-测试计划
- 微信小程序开发 不在以下合法域名列表中请参考文档 解决方法
- 【ZOJ 2676】Network Wars 网络战争 网络流 01分数规划
- 学习中遇到的几个棘手的问题,很关键
- struct来处理C语言中的结构体
- 个人技能知识图谱
- Java复习之Object类
- java中的synchronized两种用法
- 39:Reorder List
- 可运行于Windows 10 UWP的Python解释器
- VTK读取一个TXT文档中的三维点坐标显示三维点云