zoukankan      html  css  js  c++  java
  • [Cogs727] [网络流24题#2] 太空飞行计划 [网络流,最小割]

    建图:源点—(w[i])—>实验—(∞)—>仪器—(cost[i])—>汇点,

    如果该实验造成收益,则仪器到汇点的边在最小割中,

    如果该实验造成损失,则源点到实验的边在最小割中,

    故答案就是所有实验的所有收益(不考虑仪器花费的)减去最小割。

    特别注意,最后统计方案时,不能直接判断边权是否为0,因为当花费等于收益时,这种方法会将该实验计入答案而题目则不允许,故应该在最后Bfs出的level数组中判断是否可达,再通过实验把所需仪器统计出来。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <algorithm>
      8 #include <queue>
      9 #include <vector>
     10 
     11 using namespace std;
     12 
     13 template<const int _n>
     14 struct Edge
     15 {
     16     struct Edge_base { int    to,next,w; }e[_n];
     17     int    p[_n],cnt;
     18     Edge()    { clear(); }
     19     inline int    start(const int x) { return p[x]; }
     20     inline void    insert(const int x,const int y,const int z)
     21     { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; p[x]=cnt; return ; }
     22     inline Edge_base&    operator[](const int x) { return e[x]; }
     23     inline void    clear() { cnt=1,memset(p,0,sizeof(p)); }
     24 };
     25 
     26 int    n,m,SSS,TTT;
     27 int    w[210],cost[210];
     28 int    level[210],cur[210];
     29 char    str[11000];
     30 Edge<25000>    e;
     31 vector<pair<int,int> >    vec;
     32 
     33 bool    Bfs(const int S)
     34 {
     35     int    i,t;
     36     queue<int>    Q;
     37     memset(level,0,sizeof(int)*(n+m+3));
     38     level[S]=1;Q.push(S);
     39     while(!Q.empty())
     40     {
     41         t=Q.front(),Q.pop();
     42         for(i=e.start(t);i;i=e[i].next)
     43         {
     44             if(!level[e[i].to] && e[i].w)
     45             {
     46                 level[e[i].to]=level[t]+1;
     47                 Q.push(e[i].to);
     48             }
     49         }
     50     }
     51     return    level[TTT];
     52 }
     53 
     54 int    Dfs(const int S,const int bk)
     55 {
     56     if(S==TTT)return bk;
     57     int    rest=bk;
     58     for(int &i=cur[S];i;i=e[i].next)
     59     {
     60         if(level[e[i].to]==level[S]+1 && e[i].w)
     61         {
     62             int    flow=Dfs(e[i].to,min(rest,e[i].w));
     63             e[i].w-=flow;
     64             e[i^1].w+=flow;
     65             if((rest-=flow)<=0)break;
     66         }
     67     }
     68 
     69     if(rest==bk)level[S]=0;
     70     return bk-rest;
     71 }
     72 
     73 int    Dinic()
     74 {
     75     int    i,j,flow=0;
     76     int    Ans[210]={0};
     77     while(Bfs(SSS))
     78     {
     79         memcpy(cur,e.p,sizeof(int)*(n+m+3));
     80         flow+=Dfs(SSS,0x3f3f3f3f);
     81     }
     82 
     83     for(i=1;i<=n;++i)
     84     {
     85         if(level[i])
     86         {
     87             printf("%d ",i);
     88             for(j=e.start(i);j;j=e[j].next)
     89                 Ans[e[j].to-n]=1;
     90         }
     91     }
     92     printf("
    ");
     93     for(i=1;i<=m;++i)
     94     {
     95         if(Ans[i])printf("%d ",i);
     96     }
     97     printf("
    ");
     98 
     99     return flow;
    100 }
    101 
    102 void    Build()
    103 {
    104     int    i;
    105     SSS=n+m+1,TTT=n+m+2;
    106     for(i=1;i<=n;++i)
    107     {
    108         e.insert(SSS,i,w[i]);
    109         e.insert(i,SSS,0);
    110     }
    111     for(i=0;i<(int)vec.size();++i)
    112     {
    113         e.insert(vec[i].first,vec[i].second+n,0x3f3f3f3f);
    114         e.insert(vec[i].second+n,vec[i].first,0);
    115     }
    116     for(i=n+1;i<=m+n;++i)
    117     {
    118         e.insert(i,TTT,cost[i-n]);
    119         e.insert(TTT,i,0);
    120     }
    121     return ;
    122 }
    123 
    124 #define    EOL    -1
    125 int    getint(int&    data,int & t)
    126 {
    127     char    ch;data=0;
    128     ch=str[t++];
    129     while((ch<'0' || ch>'9') && ch)ch=str[t++];
    130     while(ch>='0' && ch<='9')data=data*10+ch-48,ch=str[t++];
    131     if(!data)return EOL;
    132     return 1;
    133 }
    134 
    135 int main()
    136 {
    137     freopen("shuttle.in","r",stdin);
    138     freopen("shuttle.out","w",stdout);
    139 
    140     int    i,c,Sum=0;
    141 
    142     scanf("%d%d",&n,&m);
    143     for(i=1;i<=n;++i)
    144     {
    145         scanf("%d",&w[i]);
    146         Sum+=w[i];
    147         fgets(str,10000,stdin);
    148         int t=0;
    149         while(~getint(c,t))
    150         {
    151             vec.push_back(make_pair(i,c));
    152             if(t==-1)break;
    153         }
    154     }
    155     for(i=1;i<=m;++i)
    156     {
    157         scanf("%d",&cost[i]);
    158     }
    159 
    160     Build();
    161 
    162     printf("%d
    ",Sum-Dinic());
    163 
    164     return 0;
    165 }
    View Code
  • 相关阅读:
    卡特兰数
    poj3461 字符串匹配 熟悉kmp算法第一题
    hdu1018
    poj 1088
    Linux / OS X 实用命令
    Mac/Linux 定时运行命令行
    在Mac安装Scheme
    如何判断无向图有环
    Prime算法生成最小生成树
    无向图的深度优先与广度优先搜索代码实现
  • 原文地址:https://www.cnblogs.com/Gster/p/4989316.html
Copyright © 2011-2022 走看看