[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("\n");
 93     for(i=1;i<=m;++i)
 94     {
 95         if(Ans[i])printf("%d ",i);
 96     }
 97     printf("\n");
 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\n",Sum-Dinic());
163 
164     return 0;
165 }
View Code

 

posted @ 2015-11-23 18:42  Gster  阅读(231)  评论(0编辑  收藏  举报