zoukankan      html  css  js  c++  java
  • 图论(网络流,分数规划):COGS 2047. [ZOJ2676]网络战争

    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

      可以看看2007胡博涛的论文。
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <queue>
      5 #include <cmath>
      6 using namespace std;
      7 const int maxn=10010;
      8 const int maxm=40010;
      9 const double eps=1e-7;
     10 const int INF=10000000;
     11 int n,m,e[maxm][3];
     12 int cnt,fir[maxn],to[maxm],nxt[maxm],ID[maxm];
     13 double cap[maxn];
     14 void addedge(int a,int b,double c,int id){
     15     nxt[++cnt]=fir[a];
     16     fir[a]=cnt;
     17     ID[cnt]=id;
     18     cap[cnt]=c;
     19     to[cnt]=b;
     20 }
     21 
     22 queue<int>q;
     23 int dis[maxn];
     24 bool BFS(int s,int t){
     25     memset(dis,0,sizeof(dis));
     26     dis[t]=1;q.push(t);
     27     while(!q.empty()){
     28         int x=q.front();q.pop();
     29         for(int i=fir[x];i;i=nxt[i])
     30             if(!dis[to[i]]){
     31                 dis[to[i]]=dis[x]+1;
     32                 q.push(to[i]);
     33             }
     34     }    
     35     return dis[s];
     36 }
     37 
     38 int fron[maxn];
     39 int gap[maxn],path[maxn];
     40 double ISAP(int s,int t){
     41     if(!BFS(s,t))return 0;
     42     for(int i=s;i<=t;i++)++gap[dis[i]];
     43     for(int i=s;i<=t;i++)fron[i]=fir[i];
     44     int p=s;
     45     double f,ret=0;
     46     while(dis[s]<=t){
     47         if(p==t){
     48             f=INF;
     49             while(p!=s){
     50                 f=min(f,cap[path[p]]);
     51                 p=to[path[p]^1];                
     52             }
     53             ret+=f;p=t;
     54             while(p!=s){
     55                 cap[path[p]]-=f;
     56                 cap[path[p]^1]+=f;
     57                 p=to[path[p]^1];
     58             }
     59         }
     60         int &ii=fron[p];
     61         for(;ii;ii=nxt[ii])
     62             if(cap[ii]>eps&&dis[p]==dis[to[ii]]+1)
     63                 break;
     64         if(ii)
     65             path[p=to[ii]]=ii;
     66         else{
     67             if(--gap[dis[p]]==0)break;
     68             int minn=t+1;
     69             for(int i=fir[p];i;i=nxt[i])
     70                 if(cap[i]>eps)minn=min(minn,dis[to[i]]);
     71             ++gap[dis[p]=minn+1];ii=fir[p];
     72             if(p!=s)p=to[path[p]^1];    
     73         }            
     74     }
     75     return ret;
     76 }
     77 
     78 int ch[maxm],ans;
     79 void Init(){
     80     memset(fir,0,sizeof(fir));
     81     memset(gap,0,sizeof(gap));
     82     memset(ch,0,sizeof(ch));
     83     cnt=1;
     84 }
     85 
     86 
     87 double Solve(double lam){
     88     Init();
     89     double ret=0.0;
     90     for(int i=1;i<=m;i++){
     91         if(e[i][2]-lam<-eps){
     92             ret+=e[i][2]-lam;
     93             ch[i]=1;
     94         }
     95         else{
     96             addedge(e[i][0],e[i][1],e[i][2]-lam,i);
     97             addedge(e[i][1],e[i][0],e[i][2]-lam,i);
     98         }
     99     }
    100     ret+=ISAP(1,n);
    101     for(int i=2;i<=cnt;i++)
    102         if(fabs(cap[i])<eps&&ID[i])ch[ID[i]]=1;
    103     return ret;    
    104 }
    105 
    106 int main(){
    107 #ifndef ONLINE_JUDGE
    108     freopen("networkwar.in","r",stdin);
    109     freopen("networkwar.out","w",stdout);
    110 #endif
    111     while(true){
    112         scanf("%d%d",&n,&m);
    113         if(!n&&!m)break;
    114         for(int i=1;i<=m;i++)
    115             for(int j=0;j<=2;j++)
    116                 scanf("%d",&e[i][j]);
    117         double lo=eps,hi=INF,lam;
    118         for(int t=1;t<=30;t++){
    119             lam=(lo+hi)/2;
    120             if(Solve(lam)>eps)
    121                 lo=lam;
    122             else 
    123                 hi=lam;
    124             if(hi-lo<eps)break;    
    125         }
    126         ans=0;
    127         for(int i=1;i<=m;i++)
    128             if(ch[i])ans+=1;
    129         printf("%d
    ",ans);
    130         for(int i=1;i<=m;i++)
    131             if(ch[i])printf("%d ",i);
    132         printf("
    
    ");        
    133     }
    134     return 0;    
    135 }
  • 相关阅读:
    Oracle Instant Client(即时客户端) 安装与配置
    Windows 下 Toad 如何使用 Oracle instantclient 32位客户端
    Oracle 内存(SGA,PGA)详细介绍
    深入解析Oracle 10g中SGA_MAX_SIZE和SGA_TARGET参数的区别和作用
    Android中的Touch事件
    Activity源码简要分析总结
    Android中的Interpolator
    Android 触摸手势基础 官方文档概览
    Android中View的绘制过程 onMeasure方法简述 附有自定义View例子
    Android TextView走马灯效果
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5639189.html
Copyright © 2011-2022 走看看