Network Wars

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

题意:给出一个带权无向图 ,每条边e有一个权 。求将点 和点t分开的一个边割集 ,使得该割集的平均边权最小,即最小化:

题解:转化成求0-1分数规划,然后求最小割,注意e‘<0是直接加入割边的,对剩余边求最小割即可。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<queue>
  6 #include<cmath>
  7 #define INF 100000000
  8 using namespace std;
  9 const int N=1205;
 10 const int M=1000000;
 11 struct Node{
 12    int v;
 13    double f;
 14    int next;
 15 }edge[M];
 16 int n,m,u,v,cnt,sx,ex;
 17 int head[N],pre[N];
 18 int xx[N],yy[N];
 19 double cc[N];
 20 void init(){
 21     cnt=0;
 22     memset(head,-1,sizeof(head));
 23 }
 24 void add(int u,int v,double w){
 25     edge[cnt].v=v;
 26     edge[cnt].f=w;
 27     edge[cnt].next=head[u];
 28     head[u]=cnt++;
 29     edge[cnt].f=0;
 30     edge[cnt].v=u;
 31     edge[cnt].next=head[v];
 32     head[v]=cnt++;
 33 }
 34 bool BFS(){
 35   memset(pre,0,sizeof(pre));
 36   pre[sx]=1;
 37   queue<int>Q;
 38   Q.push(sx);
 39  while(!Q.empty()){
 40      int d=Q.front();
 41      Q.pop();
 42      for(int i=head[d];i!=-1;i=edge[i].next    ){
 43         if(edge[i].f&&!pre[edge[i].v]){
 44             pre[edge[i].v]=pre[d]+1;
 45             Q.push(edge[i].v);
 46         }
 47      }
 48   }
 49  return pre[ex]>0;
 50 }
 51 double dinic(double flow,int ps){
 52     double f=flow;
 53      if(ps==ex)return f;
 54      for(int i=head[ps];i!=-1;i=edge[i].next){
 55         if(edge[i].f&&pre[edge[i].v]==pre[ps]+1){
 56             double a=edge[i].f;
 57             double t=dinic(min(a,flow),edge[i].v);
 58               edge[i].f-=t;
 59               edge[i^1].f+=t;
 60             flow-=t;
 61              if(flow<=0)break;
 62         }
 63
 64      }
 65       if(f-flow<=0)pre[ps]=-1;
 66       return f-flow;
 67 }
 68 double solve(){
 69     double sum=0;
 70     while(BFS())
 71         sum+=dinic(INF,sx);
 72     return sum;
 73 }
 74 bool ok(double mid){
 75     init();
 76     double flow=0;
 77     for(int i=1;i<=m;i++){
 78         if(cc[i]>mid){
 79             add(xx[i],yy[i],cc[i]-mid);
 80             add(yy[i],xx[i],cc[i]-mid);
 81         }
 82         else{
 83             flow+=cc[i]-mid;
 84         }
 85     }
 86     flow+=solve();
 87     if(flow>=0)return true;
 88     return false;
 89 }
 90 bool vis[N];
 91 void DFS(int u){
 92       for(int i=head[u];i!=-1;i=edge[i].next){
 93          int v=edge[i].v;
 94          if(!vis[v]&&edge[i].f>1e-5){
 95              vis[v]=1;
 96              DFS(v);
 97          }
 98       }
 99 }
100 int ans[N],top;
101 int main() {
102     int tt=1;
103     while(cin>>n>>m){
104         sx=1;
105         ex=n;
106         if(tt>1)puts("");
107         tt=2;
108         for(int i=1;i<=m;i++){
109             cin>>xx[i]>>yy[i]>>cc[i];
110         }
111         double l=0,r=1000000;
112       while(abs(l-r)>1e-5){
113           double mid=(l+r)/2;
114           if(ok(mid)){
115             l=mid;
116           }
117           else{
118             r=mid;
119           }
120       }
121         ok(r);
122        memset(vis,0,sizeof(vis));
123        vis[1]=1;
124        DFS(1);
125        top=0;
126        for(int i=1;i<=m;i++){
127           if(vis[xx[i]]+vis[yy[i]]==1||cc[i]<=r){
128              ans[++top]=i;
129           }
130        }
131        printf("%d\n",top);
132        sort(ans+1,ans+top+1);
133        for(int i=1;i<top;i++)
134         printf("%d ",ans[i]);
135        printf("%d\n",ans[top]);
136
137     }
138     return 0;
139 }

时间: 2024-10-13 02:23:08

Network Wars的相关文章

ZJU 2676 Network Wars

Network Wars Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Original ID: 267664-bit integer IO format: %lld      Java class name: Main Special Judge Network of Byteland consists of n servers, connected by m optical cable

ZOJ 2676 Network Wars(最优比例最小割)

Network Wars Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge Network of Byteland consists of n servers, connected by m optical cables. Each cable connects two servers and can transmit data in both directions. Two servers of the n

zoj 2676 Network Wars(最小割,01分数规划)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2676 大致题意:给出一个带权无向图,每条边有一个边权wi,求将S和T分开的一个割边集C,使得该割边集的平均边权最小,即最小化∑wi / |C| . 详见amber关于最小割模型的论文 思路:amber论文中详细讲解了如何转化成函数及建图,值得注意的是当边被重新赋权后,对于wi < 0 的边权,该边必然在最小割中,不必再建边,直接加入最大流中即可,因为求最小割时边权都为正值

ZOJ 2676 Network Wars[01分数规划]

ZOJ Problem Set - 2676 Network Wars Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge Network of Byteland consists of n servers, connected by m optical cables. Each cable connects two servers and can transmit data in both direction

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

Network Wars 07年胡伯涛的论文上的题:http://wenku.baidu.com/view/87ecda38376baf1ffc4fad25.html 代码: #include <algorithm> #include <cstdio> #include <iterator> #include <limits> #include <vector> #include <string.h> const int N = 11

ASC7 Problem G. Network Wars

题目大意 给你一个$n$个点$m$条带权双向边的图,求选取割的集合,最小化$$\frac{\sum_{i\in cut}c_i}{|cut|}$$ 简要题解 01分数规划,先二分答案,然后把边权设为$c[i]-ans$,如果这个值小于0,显然要选这个边,再加上最小割的值,如果这个和小于0,则说明二分的答案太大,否则太小. 最后输出结果,方法是先bfs得到S集合,然后横跨S和T的边在割中. 1 #include <bits/stdc++.h> 2 using namespace std; 3 n

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

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2676 题意: 给出N个点和M条边,要求一个割集,使得集合中 ans = 所有边点权值和/边的数量 最小. 思路: 0-1分数规划. 具体证明参考 胡伯涛 <最小割模型在信息学竞赛中的应用> 设g = min(Σwi/Σ1) 转化为 求g使得 (Σwi - g*Σ1) = 0. 所以二分求g的值. 每次建图的时候,以1为源点,N为汇点. 原来图中每条边的容量

HDU 2676 Network Wars 01分数规划,最小割 难度:4

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)是目标式的变

网络流专栏

最大流 POJ 1273 Drainage Ditches POJ 1274 The Perfect Stall (二分图匹配) POJ 1698 Alice's Chance(构图) POJ 1459 Power Network(构图) POJ 2112 Optimal Milking (二分) POJ 2455 Secret Milking Machine (二分) POJ 3189 Steady Cow Assignment (枚举) POJ 1637 Sightseeing tour (