网络最大流SAP算法
来源:互联网 发布:unity3d简介 编辑:程序博客网 时间:2024/05/18 00:47
#include<cstdio>//拆点 将1~n的女生每个拆成两个分别为n+1到2*n,坏女生连的是和自己关系不好的男生#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int INF=0x7fffffff;int f[100010],n,m,p,k,cont,arr[1010][1010],dis[100010],gap[100010],first[100010];int cur[100010];//当前弧int exc[100010];//该点盈余int pre[100010];//前驱节点struct node{ int u,v,w; int next;} x[100010];struct zp{ int a,b;} edge[100010];int finds(int a){ int b=a; while(a!=f[a]) a=f[a]; while(b!=a) { int tmp; tmp=f[b]; f[b]=a; b=tmp; } return a;}int merger(int a,int b){ int fa=finds(a),fb=finds(b); if(fa!=fb) f[fa]=fb;}void add_edge(int a,int b,int value){ x[cont].u=a,x[cont].v=b,x[cont].w=value; x[cont].next=first[a],first[a]=cont++; x[cont].u=b,x[cont].v=a,x[cont].w=0; x[cont].next=first[b],first[b]=cont++;}void build(int flow)//建图{ cont=0; memset(first,-1,sizeof(first)); memset(arr,0,sizeof(arr)); for(int i=0; i<m; i++) { int a=edge[i].a,b=edge[i].b; arr[finds(a)][b]=1;//用老大来和自己的朋友建立关系 } for(int i=1; i<=n; i++) { add_edge(2*n+i,3*n+1,flow);//男生向汇点建边 add_edge(0,i,flow);//源点向女生建边 add_edge(i,i+n,k);//好女生向坏女生建边 for(int j=1; j<=n; j++) if(arr[finds(i)][j]) add_edge(i,2*n+j,1);//如果老大和该男生是朋友则自己也和该男生是朋友 else add_edge(i+n,2*n+j,1);//否则不是朋友 }}int SAP(int s,int e,int N)//源点,汇点,总点数{ int Max_flow=0,u=s; pre[s]=-1; exc[s]=INF; memset(gap,0,sizeof(gap));//标号是i的点的个数 memset(dis,0,sizeof(dis));//距离标号 gap[0]=N; for(int i=0; i<=N; i++) //初始化当前弧 cur[i]=first[i]; while(dis[s]<N) { int flag=1; if(u==e)//找到汇点 { Max_flow+=exc[e];//更新最大流 for(int i=pre[e]; i!=-1; i=pre[i]) //更新当前允许路 { int id=cur[i]; x[id].w-=exc[e]; x[id^1].w+=exc[e]; exc[i]-=exc[e]; if(x[id].w==0) u=i;//退回到容量为0的弧尾 } } for(int i=cur[u]; i!=-1; i=x[i].next) //从当前弧开始寻找允许弧 { int v=x[i].v; if(x[i].w>0&&dis[u]==dis[v]+1)//找到允许弧 { flag=0;//找到允许弧 cur[u]=i;//更新当前弧 pre[v]=u;//记录前驱 exc[v]=min(exc[u],x[i].w);//计算最大增广 u=v; break; } } if(flag)//没有找到允许弧 { if(--gap[dis[u]]==0) break;//出现断层结束 int minn=N; cur[u]=first[u]; for(int i=first[u]; i!=-1; i=x[i].next) //找离当前点可到达的最小层次 { int v=x[i].v; if(x[i].w>0&&dis[v]<minn) { minn=dis[v]; cur[u]=i;//修改当前弧标记 } } dis[u]=minn+1;//更新该点层次 gap[dis[u]]++;//层次点数++ if(u!=s) u=pre[u];//回溯继续寻找允许弧 } } return Max_flow;}int main(){ int ncase; scanf("%d",&ncase); while(ncase--) { scanf("%d%d%d%d",&n,&m,&k,&p); for(int i=0; i<=n; i++) f[i]=i; for(int i=0; i<m; i++) scanf("%d%d",&edge[i].a,&edge[i].b); for(int i=0; i<p; i++) { int a,b; scanf("%d%d",&a,&b); merger(a,b); } for(int i=1; i<=n; i++) f[i]=finds(i); int L=0,R=n,ans=0; while(L<=R)//二分求解 { int mid=(L+R)>>1; build(mid); if(SAP(0,3*n+1,3*n+2)==mid*n) { L=mid+1; ans=mid; } else R=mid-1; } printf("%d\n",ans); }}
0 0
- 网络最大流SAP算法
- 网络流之最大流sap算法
- 网络流最大流的sap()算法
- 网络流最大流sap算法模板
- [转载]网络最大流SAP算法心得
- 图论算法----网络流----最大流sap算法
- 最大流SAP算法
- 最大流SAP算法
- 最大流SAP算法
- 最大流-SAP算法
- 网络流最大流之SAP算法 详解
- hdu3549(网络流入门题-最大流的sap算法)
- 网络最大流(SAP)
- 最大流算法 SAP+GAP
- 最大流(SAP算法)
- 网络流的SAP算法
- 网络流之SAP算法
- 网络流sap算法(whitecloud)
- stm32/Cortex-M3的内存的4GB的存储空间
- 【codevs 4560】[NOIP2015 D2T2]子串(dp)
- Spring 框架IOC的初始化过程
- Java 简述
- Binary Tree Right Side View
- 网络最大流SAP算法
- Android--日志系统(调试信息)
- 解决iText+flying saucer+freemark导出pdf不支持base64的解决办法
- 阻塞状态的recv返回值
- 《算法》第一章——打印文件目录结构
- ThreadLocal理解
- 10.zabbix学习笔记:记一次zabbix故障引发的排查过程
- 【编程素质】设计模式-模板方法
- Node.js:request+cheerio爬虫爬取免费代理