Bzoj2561:最小生成树:网络流,最小割

来源:互联网 发布:手机mac地址全为0 编辑:程序博客网 时间:2024/05/19 14:38

题目链接:最小生成树

发现如果这条边可能出现在最大生成树上的话,那么可以代替这条边的所有边都不连通,换句话说这条边是连接u,v必不可少的

于是我们把所有权值大于L的边建成一张边权去为1的图对U,V跑最小割即可知道最少删去多少条边

最小生成树同理QAQ

#include<queue>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=255010;const int inf=0x7fffffff/3;int n,m,h[maxn],cur[maxn],tot=1;struct edge{int to,next,w;}G[maxn*6];struct edges{int a,b,w;}e[maxn*6];int vis[maxn],U,V,W,ans=0,S,T;bool bfs(){for (int i=1;i<=n;++i) vis[i]=-1;queue<int>q; q.push(S); vis[S]=0;while (!q.empty()){int u=q.front(); q.pop();for (int i=h[u];i;i=G[i].next){int v=G[i].to;if (vis[v]==-1&&G[i].w){vis[v]=vis[u]+1;q.push(v);}}}return vis[T]!=-1;}int dfs(int x,int f){if (x==T||!f) return f;int w,used=0;for (int i=cur[x];i;i=G[i].next)    if (vis[G[i].to]==vis[x]+1){w=f-used;w=dfs(G[i].to,min(G[i].w,w));G[i].w-=w; G[i^1].w+=w;used+=w; if (G[i].w) cur[x]=i;if (used==f) return f;    }if (!used) vis[x]=-1;return used;}int dinic(){int ret=0;while (bfs()){for (int i=1;i<=n;++i) cur[i]=h[i];ret+=dfs(S,inf);}return ret;}void add(int x,int y,int z){G[++tot].to=y;G[tot].w=z;G[tot].next=h[x];h[x]=tot;G[++tot].to=x;G[tot].w=z;G[tot].next=h[y];h[y]=tot;}void solve1(){for (int i=1;i<=m;++i)    if (e[i].w>W) add(e[i].a,e[i].b,1);ans=dinic();}void solve2(){memset(h,0,sizeof(h)); tot=1;for (int i=1;i<=m;++i)    if (e[i].w<W) add(e[i].a,e[i].b,1);ans+=dinic();}int main(){scanf("%d%d",&n,&m);for (int i=1;i<=m;++i)    scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].w);scanf("%d%d%d",&U,&V,&W);S=U; T=V;solve1(); solve2();printf("%d",ans);}


2 0
原创粉丝点击