cogs 2047. [ZOJ2676]网络战争 (最小割+01分数规划)
2017-01-15 08:36
519 查看
2047. [ZOJ2676]网络战争
★★★ 输入文件:networkwar.in输出文件:
networkwar.out
评测插件
时间限制:5 s 内存限制:32 MB
【题目描述】
Byteland的网络是由n个服务器和m条光纤组成的,每条光纤连接了两个服务器并且可以双向输送信息。这个网络中有两个特殊的服务器,一个连接到了全球的网络,一个连接到了总统府,它们的编号分别是1和N.最近一家叫做Max Traffic的公司决定控制几条网络中的光纤,以使他们能够掌握总统府的的上网记录。为了到达这个目的,他们需要使所有从1号服务器到N号服务器的数据都经过至少一条他们所掌握的线路。
为了把这个计划付诸于行动,他们需要从这些线路的拥有者手中购买线路,每条线路都有对应的花费。自从公司的主要业务部是间谍活动而是家用宽带以后,经理就希望尽可能少的花费和尽可能高的回报。因此我们要使购买线路的平均值最小。
如果我们购买了k条线路,花费了c元,我们希望找到使c/k最小的方案。
【输入格式】
多组数据,每组数据第一行是两个整数n和m(1<=n<=100,1<=m<=400),代表服务器的个数和线路数之后的m行,每行三个整数a,b,c,分别代表了这条线路所连接的服务器和购买这条线路的花费,花费都是正数且不会超过10^7
没有自边,没有重边,保证任意两点都是连通的。
最后一行为两个0
【输出格式】
每组数据的第一行是一个整数k,代表购买多少条线路之后k个整数,代表购买线路的编号,编号是它们在输入文件被给处的顺序
每组数据之间有一个空行
【样例输入】
6 8 1 2 3 1 3 2 2 4 2 2 5 2 3 4 2 3 5 2 5 6 3 4 6 3 4 5 1 2 2 1 3 2 2 3 1 2 4 2 3 4 2 0 0
【样例输出】
4 3 4 5 6 3 1 2 3
【提示】
在此键入。【来源】
在此键入。题解:最小割+01分数规划
这道题其实就是求割集中的sigma(ci)/|c| ,按照01分数规划的套路,对式子进行变形。
xi∈{0,1},若边在割集中则xi=1,否则xi=0, 最小值R=sigma ci*xi/sigma xi
然后进行二分判定,二分L,求是否满足条件的sigma xi*(ci-L)<=eps
如何求最小割呢?我们将所有边的边权改为(ci-L),如果边权为负数,那么直接加入答案。否则加边求用最大流求最小割。如果最后的计算结果<=eps那说明L还可以更小
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define N 4003
#define inf 1000000000
#define eps 1e-7
using namespace std;
int m,n,tot;
int point
,v
,next
,last
,deep
,num
,cur
;
int a
,b
,ck
,mark
,id
;
double c
,remain
;
void add(int x,int y,double z,int k)
{
tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; remain[tot]=z; id[tot]=k;
}
double addflow(int s,int t)
{
int now=t; double ans=inf;
while (now!=s) {
ans=min(ans,remain[last[now]]);
now=v[last[now]^1];
}
now=t;
while (now!=s) {
remain[last[now]]-=ans;
remain[last[now]^1]+=ans;
now=v[last[now]^1];
}
return ans;
}
void bfs(int s,int t)
{
for (int i=1;i<=t;i++) deep[i]=t;
queue<int> p; p.push(t); deep[t]=0;
while (!p.empty()) {
int now=p.front(); p.pop();
for (int i=point[now];i!=-1;i=next[i])
if (deep[v[i]]==t&&remain[i^1]>eps)
deep[v[i]]=deep[now]+1,p.push(v[i]);
}
}
double isap(int s,int t)
{
double ans=0; int now=s;
bfs(s,t);
for (int i=1;i<=t;i++) num[deep[i]]++;
for (int i=1;i<=t;i++) cur[i]=point[i];
while (deep[s]<t) {
if (now==t) {
ans+=addflow(s,t);
now=s;
}
bool pd=false;
for (int i=cur[now];i!=-1;i=next[i])
if (deep[now]==deep[v[i]]+1&&remain[i]>eps){
last[v[i]]=i;
cur[now]=i;
now=v[i];
pd=true;
break;
}
if (!pd) {
int minn=t;
for (int i=point[now];i!=-1;i=next[i])
if (remain[i]>eps) minn=min(minn,deep[v[i]]);
if (!--num[deep[now]]) break;
num[deep[now]=minn+1]++;
cur[now]=point[now];
if (now!=s) now=v[last[now]^1];
}
}
return ans;
}
bool check(double x)
{
tot=-1;
memset(point,-1,sizeof(point));
memset(num,0,sizeof(num));
memset(ck,-1,sizeof(ck));
double sum=0;
for (int i=1;i<=m;i++)
if (c[i]-x<-eps) sum+=(c[i]-x),ck[i]=1;
else add(a[i],b[i],c[i]-x,i),add(b[i],a[i],c[i]-x,i);
double t=isap(1,n);
sum+=t;
return sum<=eps;
}
int main()
{
freopen("networkwar.in","r",stdin);
freopen("networkwar.out","w",stdout);
while (true) {
scanf("%d%d",&n,&m);
memset(mark,0,sizeof(mark));
if (!n&&!m) break;
double l=0; double r=1e7;
for (int i=1;i<=m;i++) scanf("%d%d%lf",&a[i],&b[i],&c[i]);
double ans=r;
while (r-l>=eps) {
double mid=(l+r)/2;
if (check(mid)) ans=min(ans,mid),r=mid;
else l=mid;
}
int size=0;
for (int i=0;i<=tot;i++)
if (id[i]&&fabs(remain[i])<eps) ck[id[i]]=1;
for (int i=1;i<=m;i++) if (ck[i]==1) size++;
printf("%d\n",size);
for (int i=1;i<=m;i++)
if (ck[i]==1) printf("%d ",i);
printf("\n\n");
}
}
相关文章推荐
- cogs 2047 [ZOJ2676]网络战争 (最小割+01分数规划)
- 图论(网络流,分数规划):COGS 2047. [ZOJ2676]网络战争
- 【ZOJ2676】Network Wars 最小割+01分数规划
- 【ZOJ 2676】Network Wars 网络战争 网络流 01分数规划
- poj-2728-Desert King-01分数规划+最小生成树
- 最小比例生成树(01分数规划)二分或迭代
- BZOJ 1486: [HNOI2009]最小圈 [01分数规划]
- Desert King(01分数规划+最小生成树prim算法)
- zoj 2676 Network Wars(01分数规划+最小割)
- 【最小割模型、01分数规划】zoj2676Network Wars
- 【BZOJ1486】[HNOI2009]最小圈【SPFA判负环】【01分数规划】
- Network Wars-ZOJ2676最小割+01规划
- 【ZOJ】2676 Network Wars 01分数规划+最小割
- 最大密集子图(01分数规划+二分+最小割)POJ3155
- ZOJ 2676 Network Wars(01分数规划-二分+最小割)
- ZOJ 2676 Network Wars ★(最小割算法介绍 && 01分数规划)
- 最小比例生成树(01分数规划)二分或迭代
- HDU 2676 Network Wars 01分数规划,最小割 难度:4
- [省选前题目整理][BZOJ 1486][HNOI 2009]最小圈(01分数规划)
- bzoj1486 [HNOI2009]最小圈 【最小比例环 01分数规划】