Smallest Minimum Cut HDU - 6214 最少边的最小割
结论题,加边的时候每个边容量扩大为cap*(Edge+1)+1,跑一边最大流%(Edge+1)就是最少边数了
证明一下就是一个容量为8的边和两个容量为4的边,扩大后只有堵住原先8才是最小的
新最大流:maxflow*(Edge+1)+最少割边数
#include<bits/stdc++.h> using namespace std; #define ll long long const int maxn=2e5+7; const int inf=0x3f3f3f3f; int num_nodes; int tot; int d[maxn],cur[maxn],source,sink; int p[maxn],num[maxn],vis[maxn]; struct EDGE{ int from,to,cap,flow; }; vector<EDGE>edge; vector<int>G[maxn]; void init(){ edge.clear(); for(int i=0;i<maxn;i++)G[i].clear(); } void addedge(int u,int v,int w){ edge.push_back((EDGE){u,v,w,0}); edge.push_back((EDGE){v,u,0,0}); tot=edge.size(); G[u].push_back(tot-2); G[v].push_back(tot-1); } int bfs(){ memset(vis,0,sizeof vis); queue<int>Q; Q.push(sink); vis[sink]=1; d[sink]=0; while(!Q.empty()){ int u=Q.front(); Q.pop(); int sz=G[u].size(); for(int i=0;i<sz;++i){ EDGE &e=edge[G[u][i]^1]; if(!vis[e.from] && e.cap>e.flow){ vis[e.from]=1; d[e.from]=d[u]+1; Q.push(e.from); } } } return vis[source]; } int augment(){ int u=sink,a=inf; while(u!=source){ EDGE &e=edge[p[u]]; a=min(a,e.cap-e.flow); u=edge[p[u]].from; } u=sink; while(u!=source){ edge[p[u]].flow+=a; edge[p[u]^1].flow-=a; u=edge[p[u]].from; } return a; } int maxflow(){ int flow=0; bfs(); memset(num,0,sizeof num); for(int i=0;i<num_nodes;i++)num[d[i]]++; int u=source; memset(cur,0,sizeof cur); while(d[source]<num_nodes){ if(u==sink){ flow+=augment(); u=source; } int advance=0; int sz=G[u].size(); for(int i=cur[u];i<sz;i++){ EDGE &e=edge[G[u][i]]; if(e.cap>e.flow && d[u]==d[e.to]+1){ advance=1; p[e.to]=G[u][i]; cur[u]=i; u=e.to; break; } } if(!advance){ int m=num_nodes-1; int sz=G[u].size(); for(int i=0;i<sz;i++){ if(edge[G[u][i]].cap>edge[G[u][i]].flow){ m=min(m,d[edge[G[u][i]].to]); } } if(--num[d[u]]==0)break; num[d[u]=m+1]++; cur[u]=0; if(u!=source)u=edge[p[u]].from; } } return flow; } int main(){ int T;scanf("%d",&T); while(T--){ init(); int n,m;scanf("%d%d",&n,&m); num_nodes=n+10; scanf("%d%d",&source,&sink); for(int i=1,u,v,w;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); addedge(u,v,w*(m+1)+1);//addedge(v,u,w*(m+1)+1); } printf("%d\n",maxflow()%(m+1)); } }