Usaco Training Section 4.4 Pollutant Control
阿新 • • 發佈:2018-11-12
裸的最小割題。求最小割和刪掉的邊(使得刪掉的邊最少)
第一問很簡單,用“最大流=最小割”定理,直接求最大流即可。第二問我們可以將每條邊從大到小排序,刪掉這條邊,再跑最大流,如果刪後最大流和原來最大流的差等於這條邊,那麼我們就選這條邊,用sum加上這條邊,直到sum=原來最大流就可結束。
注意:刪掉的邊要按遞增序排。
#include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define inf 1<<29 #define mp make_pair #define pii pair<int,int> #define pb push_back using namespace std; inline int read(){ int x=0;char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x; } int c[40][40],f[40][40],n,m,s,t,d[40]; inline bool bfs(){ memset(d,0,sizeof(d)); queue<int> q; q.push(s);d[s]=1; while(!q.empty()){ int u=q.front();q.pop(); for(int v=1;v<=n;++v){ if(c[u][v]>f[u][v]&&!d[v]){ q.push(v); d[v]=d[u]+1; if(v==t) return 1; } } } return 0; } inline int dinic(int u,int flow){ if(u==t) return flow; int rest=flow; for(int v=1;v<=n;++v){ if(c[u][v]>f[u][v]&&d[v]==d[u]+1){ int k=dinic(v,min(rest,c[u][v]-f[u][v])); if(!k) d[v]=0; f[u][v]+=k; f[v][u]-=k; rest-=k; } } return flow-rest; } inline int maxf(){ int flow=0,maxflow=0; while(bfs()){ while(flow=dinic(s,inf)) maxflow+=flow; } return maxflow; } struct node{ int u,v,w,i; }ed[2005]; inline bool cmp(node x,node y){ return x.w>y.w; } int a[2005],ans; int main() { freopen("milk6.in","r",stdin); freopen("milk6.out","w",stdout); n=read(),m=read(); s=1,t=n; for(int i=1;i<=m;++i){ ed[i].u=read(),ed[i].v=read(),ed[i].w=read(),ed[i].i=i; c[ed[i].u][ed[i].v]+=ed[i].w; } int maxflow=maxf(),sum=0; printf("%d ",maxflow); sort(ed+1,ed+m+1,cmp); for(int i=1;i<=m;++i){ memset(f,0,sizeof(f)); c[ed[i].u][ed[i].v]-=ed[i].w; int s=maxf(); if(s+ed[i].w==maxflow){ a[++ans]=ed[i].i; sum+=ed[i].w; if(sum==maxflow) break; } c[ed[i].u][ed[i].v]+=ed[i].w; } printf("%d\n",ans); sort(a+1,a+ans+1); for(int i=1;i<=ans;++i) printf("%d\n",a[i]); return 0; }