码迷,mamicode.com
首页 > 其他好文 > 详细

USACO 4.4 Pollutant Control (网络流求最小割割集)

时间:2017-02-02 20:50:43      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:scan   return   begin   cond   name   air   argc   nim   back   

Pollutant Control
Hal Burch

It‘s your first day in Quality Control at Merry Milk Makers, and already there‘s been a catastrophe: a shipment of bad milk has been sent out. Unfortunately, you didn‘t discover this until the milk was already into your delivery system on its way to stores. You know which grocer that milk was destined for, but there may be multiple ways for the milk to get to that store.

The delivery system is made up of a several warehouses, with trucks running from warehouse to warehouse moving milk. While the milk will be found quickly, it is important that it does not make it to the grocer, so you must shut down enough trucks to ensure that it is impossible for the milk to get to the grocer in question. Every route costs a certain amount to shut down. Find the minimum amount that must be spent to ensure the milk does not reach its destination, along with a set of trucks to shut down that achieves this goal at that cost.

PROGRAM NAME: milk6

INPUT FORMAT

Line 1: Two space separated integers, N and M. N (2 <= N <= 32) is the number of warehouses that Merry Milk Makers has, and M (0 <= M <= 1000) is the number of trucks routes run. Warehouse 1 is actually the productional facility, while warehouse N is the grocer to which which the bad milk was destined.
Line 2..M+1: Truck routes: three space-separated integers, Si, Ei, and Ci. Si and Ei (1 <= Si,Ei <= N) correspond to the pickup warehouse and dropoff warehouse for the truck route. Ci (0 <= Ci <= 2,000,000) is the cost of shutting down the truck route.

SAMPLE INPUT (file milk6.in)

4 5
1 3 100
3 2 50
2 4 60
1 2 40
2 3 80

OUTPUT FORMAT

The first line of the output should be two integers, C and T. C is the minimum amount which must be spent in order to ensure the our milk never reaches its destination. T is the minimum number of truck routes that you plan to shut down in order to achive this goal. The next T lines sould contain a sorted list of the indexes of the truck routes that you suggest shutting down. If there are multiple sets of truck routes that achieve the goal at minimum cost, choose one that shuts down the minimum number of routes. If there are still multiple sets, choose the one whose initial routes have the smallest index.

SAMPLE OUTPUT (file milk6.out)

60 1
3

———————————————————————————————————————题解
第一次写最小割解集,总结一下
【1】最小割在数值上等于最大流
【2】在残余网络中求与源点s相连的点集S,其余的点是T
【3】最小割的割集就是一个点在S一个点在T中的弧
这是求出一个割集的方法,如果要求所有的话,我们不断的从刚才求到割集中T中的点再做floodfill直到不能再更新为止
然后就可以做完了,这个做法好像是来自WC2007的……和nocow里的不一样,nocow的题解写了一下,会T,也不知道是不是我写的不优美
但是这个0.000都可以过的
  1 /*
  2 ID: ivorysi
  3 LANG: C++
  4 TASK: milk6
  5 */
  6 #include <iostream>
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <queue>
 11 #include <set>
 12 #include <vector>
 13 #include <string.h>
 14 #define siji(i,x,y) for(int i=(x);i<=(y);++i)
 15 #define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
 16 #define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
 17 #define sigongzi(j,x,y) for(int j=(x);j>(y);--j)
 18 #define inf 0x7fffffff
 19 #define ivorysi
 20 #define mo 97797977
 21 #define hash 974711
 22 #define base 47
 23 #define pss pair<string,string>
 24 #define MAXN 30005
 25 #define fi first
 26 #define se second
 27 #define pii pair<int,int>
 28 using namespace std;
 29 struct node {
 30     int to,next,val;
 31 }edge[3005];
 32 int head[40],sum=1,n,m;
 33 void add(int u,int v,int c) {
 34     edge[++sum].to=v;
 35     edge[sum].val=c;
 36     edge[sum].next=head[u];
 37     head[u]=sum;
 38 }
 39 void addtwo(int u,int v,int c) {
 40     add(u,v,c);
 41     add(v,u,0);
 42 }
 43 int dis[40],gap[40],used[40];
 44 int sap(int u,int aug) {
 45     if(u==n) return aug;
 46     int flow=0,dmin=n-1;
 47     for(int i=head[u];i;i=edge[i].next) {
 48         int v=edge[i].to;
 49         if(edge[i].val!=0) {
 50             if(dis[v]+1==dis[u]) {
 51                 int t=sap(v,min(edge[i].val,aug-flow));
 52                 flow+=t;
 53                 edge[i].val-=t;
 54                 edge[i^1].val+=t;
 55                 if(dis[1]>=n) return flow;
 56                 if(flow==aug) break;
 57             }
 58             dmin=min(dmin,dis[v]);
 59         }
 60     }
 61     if(!flow) {
 62         --gap[dis[u]];
 63         if(gap[dis[u]]==0) dis[1]=n;
 64         dis[u]=dmin+1;
 65         ++gap[dis[u]];
 66     }
 67     return flow;
 68 }
 69 void init() {
 70     scanf("%d%d",&n,&m);
 71     int u,v,c;
 72     siji(i,1,m) {
 73         scanf("%d%d%d",&u,&v,&c);
 74         used[u]=1;used[v]=1;
 75         addtwo(u,v,c);
 76     }
 77 }
 78 int s[40],num=inf,lay=0;
 79 vector<int> ans,temp,list;
 80 void dfs(int u) {//floodfill
 81     if(s[u]) return;
 82     s[u]=1;++lay;
 83     for(int i=head[u];i;i=edge[i].next) {
 84         if(edge[i].val!=0) {
 85             dfs(edge[i].to);
 86         }
 87     }
 88 }
 89 void solve() {
 90     init();
 91     int mincut=0;
 92     while(dis[1]<n) {
 93         mincut+=sap(1,inf);
 94     }
 95     siji(i,1,n) {
 96         if(used[i]==0) {
 97             ++lay;s[i]=1;
 98         }
 99     }
100     dfs(1);
101     if(mincut==0) num=0;
102     while(lay<n) {
103         if(num==0) break;
104         siji(i,1,n) {
105             if(s[i]) {
106                 for(int j=head[i];j;j=edge[j].next) {
107                     if(j%2==0 && !s[edge[j].to]) {
108                         temp.push_back(j/2);
109                         list.push_back(edge[j].to);
110                     }
111                 }
112             }
113         }
114         if(temp.size()==0) break;//再也找不到最小割就退出
115         if(temp.size()<num) {
116             num=temp.size();
117             ans=temp;
118             sort(ans.begin(),ans.end());
119         }
120         else if(temp.size()==num) {
121             sort(temp.begin(),temp.end());
122             bool flag=0;
123             xiaosiji(i,0,num) {
124                 if(temp[i]<ans[i]) {flag=1;break;}
125             }
126             if(flag) ans=temp;
127         }
128         xiaosiji(i,0,list.size()) {
129             dfs(list[i]);
130         }
131         temp.clear();
132     }
133     printf("%d %d\n",mincut,num);
134     xiaosiji(i,0,num) {
135         printf("%d\n",ans[i]);
136     }
137 } 
138 int main(int argc, char const *argv[])
139 {
140 #ifdef ivorysi
141     freopen("milk6.in","r",stdin);
142     freopen("milk6.out","w",stdout);
143 #else
144     freopen("f1.in","r",stdin);
145 #endif
146     solve();
147     return 0;
148 }

 

 

USACO 4.4 Pollutant Control (网络流求最小割割集)

标签:scan   return   begin   cond   name   air   argc   nim   back   

原文地址:http://www.cnblogs.com/ivorysi/p/6361587.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!