[USACO4.4.2 Pollutant Control]
2012-03-06 08:02
274 查看
[关键字]:图论 网络流
[题目大意]:在一个网络里求一个割,而且要保证(1)、容量最小(就是最小割)。(2)、满足医(1)的情况小边最少。(3)、满足(1)(2)情况下边的字典序最小。
//=========================================================================================================================================
[分析]:第一二问可以将每个边的权值c改成C=c*(M+1)+1,然后在求最小割maxf。第一问答案就是maxf/(M+1)第二问答案就是maxf mod (M+1),因为此时的最小割容量Cmin=cmin*(M+1)+min(sum 1),cmin就是原来的最小割, 因为没有一个1就代表有一条边,所以min(sum 1)代表最小边数。第三问比较麻烦,首先如果一条边在最小割里那删掉它后,最大流流量回减少这条边的权值。再者如果一条边在最小割里那么删掉这条边后原先包含这条边的最小割仍旧是最小割,所以不用担心最小割出错。这样可以用枚举的方法从小到大枚举每一条边判断是否属于最小割,然后删掉再继续重复。
http://hi.baidu.com/mengyun1993/blog/item/c30d193c9a85932870cf6cda.html Orz!!!
[代码]:
View Code
[题目大意]:在一个网络里求一个割,而且要保证(1)、容量最小(就是最小割)。(2)、满足医(1)的情况小边最少。(3)、满足(1)(2)情况下边的字典序最小。
//=========================================================================================================================================
[分析]:第一二问可以将每个边的权值c改成C=c*(M+1)+1,然后在求最小割maxf。第一问答案就是maxf/(M+1)第二问答案就是maxf mod (M+1),因为此时的最小割容量Cmin=cmin*(M+1)+min(sum 1),cmin就是原来的最小割, 因为没有一个1就代表有一条边,所以min(sum 1)代表最小边数。第三问比较麻烦,首先如果一条边在最小割里那删掉它后,最大流流量回减少这条边的权值。再者如果一条边在最小割里那么删掉这条边后原先包含这条边的最小割仍旧是最小割,所以不用担心最小割出错。这样可以用枚举的方法从小到大枚举每一条边判断是否属于最小割,然后删掉再继续重复。
http://hi.baidu.com/mengyun1993/blog/item/c30d193c9a85932870cf6cda.html Orz!!!
[代码]:
View Code
/* ID:procedure2 PROB:milk6 LANG:C++ */ #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; struct node { int x,y; long long d; }e[1002]; int N,M,tot,INF,S,T; int num[33],h[33]; long long c[33][33],c1[33][33],c2[33][33]; void Init() { scanf("%d%d",&N,&M); for (int i=1;i<=M;i++) { int x,y,d; scanf("%d%d%d",&x,&y,&d); if (d) { e[++tot].x=x,e[tot].y=y; e[tot].d=(long long)(d*1001)+(long long)(1); c[x][y]+=e[tot].d; INF+=e[tot].d; } } S=1,T=N; //printf("%d\n",tot); //for (int i=1;i<=tot;i++) printf("%d %d %d\n",e[i].x,e[i].y,e[i].d); } long long Find(int u,long long flow) { if (u==T) return flow; long long temp=flow; int pos=N-1; for (int i=1;i<=N;i++) { if (h[u]==h[i]+1 && c1[u][i]) { long long f=Find(i,min(c1[u][i],temp)); temp-=f; c1[u][i]-=f; c1[i][u]+=f; //cout<<u<<' '<<i<<' '<<f<<endl; if (h[S]==N || !temp) return flow-temp; } if (c1[u][i] && pos>h[i]) pos=h[i]; } if (temp==flow) { num[h[u]]--; if (!num[h[u]]) h[S]=N; else { h[u]=pos+1; //printf("%d %d\n",u,h[u]); num[h[u]]++; } } //printf("%d %d %d\n",u,h[u],pos); return flow-temp; } long long SAP() { memcpy(c1,c,sizeof(c)); memset(h,0,sizeof(h)); memset(num,0,sizeof(num)); num[0]=N; /*for (int i=1;i<=N;i++) for (int j=1;j<=N;j++) if (c1[i][j]) printf("%d %d %lld\n",i,j,c1[i][j]);*/ long long ans=0; while (h[S]<N) ans+=Find(S,INF); return ans; } void Solve() { long long maxf=SAP(); //printf("%ld\n",maxf); printf("%ld ",maxf/1001); printf("%ld\n",maxf%1001); memcpy(c2,c1,sizeof(c1)); for (int i=1;i<=tot;i++) if (!c2[e[i].x][e[i].y]) { c[e[i].x][e[i].y]-=e[i].d; long long t=SAP(); //printf("%d %d\n",maxf,t); if (maxf-t==e[i].d) { printf("%d\n",i); maxf=t; memcpy(c2,c1,sizeof(c1)); } else c[e[i].x][e[i].y]+=e[i].d; //printf("%d\n",c2[e[i].x][e[i].y]); } } int main() { freopen("milk6.in","r",stdin); freopen("milk6.out","w",stdout); Init(); Solve(); return 0; }
相关文章推荐
- usaco training 4.4.2 Pollutant Control 追查坏牛奶 题解
- USACO 4.4.2 Pollutant Control追查坏牛奶 题解与分析
- usaco 4.4.2 Pollutant Control
- Pollutant Control_usaco 4.4_网络流
- 求割边最少的最小割(P1344 [USACO4.4]追查坏牛奶Pollutant Control)
- USACO 4.4 Pollutant Control (网络流求最小割割集)
- 洛谷 P1344 [USACO4.4]追查坏牛奶Pollutant Control
- USACO 4.4 Pollutant Control
- USACO Pollutant Control 解题报告
- P1344 [USACO4.4] 追查坏牛奶Pollutant Control
- usaco Pollutant Control
- usaco Pollutant Control
- 洛谷P1344 [USACO4.4]追查坏牛奶Pollutant Control(网络流, 最大流最小割)
- USACO 4.4 Pollutant Control
- USACO4.4.2 Pollutant Control (milk6)
- USACO4.4.2 Pollutant Control (milk6)
- USACO 4.4.2 milk6
- usaco --4.4.2--Pollutant Control
- 【usaco】4.4.2最小割集PROB Pollutant Control
- USACO Section 4.4 Pollutant Control