HDU3081 使用Floyd传递关系,二分最大流
2015-09-24 12:32
363 查看
再记录下,使用Floyd 传递关系的用法,同时把模板更新了写法,看起来更酷。
#include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; #define cl(a,b) memset(a,b,sizeof(a)) const int maxn=505; const int inf=1<<28; template<int nv,int ne>//<顶点的数量,边的数量> struct isap{ int n,size; int head[nv]; int dis[nv],gap[nv],cur[nv],pre[nv]; int maxflow; struct edge{ int v,w,next; edge(){} edge(int _v,int _w,int _next):v(_v),w(_w),next(_next){} }E[ne]; void init(int n){ this->n=n,size=0; cl(head,-1); } void insert(int u,int v,int w){ E[size]=edge(v,w,head[u]); head[u]=size++; E[size]=edge(u,0,head[v]); head[v]=size++; } int maxFlow(int src,int des){ maxflow=0; for(int i=0;i<=n;i++){ dis[i]=gap[i]=0; cur[i]=head[i]; } int u=pre[src]=src; int aug=0;///or aug=-1 while(dis[src]<n){ loop:for(int &i=cur[u];i!=-1;i=E[i].next){ int v=E[i].v; if(E[i].w&&dis[u]==dis[v]+1){ aug=min(aug,E[i].w); pre[v]=u; u=v; if(v==des){ maxflow+=aug; for(u=pre[u];v!=src;v=u,u=pre[u]){ E[cur[u]].w-=aug; E[cur[u]^1].w+=aug; } aug=inf; } goto loop; } } int mdis=n; for(int i=head[u];i!=-1;i=E[i].next){ int v=E[i].v; if(E[i].w&&mdis>dis[v]){ cur[u]=i; mdis=dis[v]; } } if(--gap[dis[u]]==0)break; gap[dis[u]=mdis+1]++; u=pre[u]; } return maxflow; } }; isap<500,500*500> G; int mp[maxn][maxn];//存关系图 int f[maxn][maxn];//表示x,y是有关系的 void Floyd(int n){//Floyd 传递关系 for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++)if(f[i][k]){ for(int j=1;j<=n;j++)if(f[k][j]){ f[i][j]=1; } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++)if(f[i][j]){ for(int k=1;k<=n;k++)if(mp[j][k]){ mp[i][k]=1; } } } } void buildMap(int k,int n,int m){ G.init(n*2+1); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++)if(mp[i][j]){ G.insert(i,j+n,1); } } for(int i=1;i<=n;i++){ G.insert(0,i,k); G.insert(i+n,n*2+1,k); } } int main(){ int T; scanf("%d",&T); while(T--){ int n,m,t; scanf("%d%d%d",&n,&m,&t); cl(mp,0); for(int i=0;i<m;i++){ int x,y; scanf("%d%d",&x,&y); mp[x][y]=1; } cl(f,0); for(int i=0;i<t;i++){ int x,y; scanf("%d%d",&x,&y); f[x][y]=f[y][x]=1; } Floyd(n); int ans=-1; int l=0,r=n; while(l<=r){ int mid=l+r>>1; buildMap(mid,n,m); if(G.maxFlow(0,2*n+1)>=n*mid){ l=mid+1; ans=mid; } else { r=mid-1; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- 混沌,分形与人工智能
- HttpURLConnection访问Webapi代码
- github for windows 安装失败解决方案(亲测)
- weblogic jvm -Dsun.zip.disableMemoryMapping=true
- 一只简单的网络爬虫(基于linux C/C++)————利用正则表达式解析页面
- 如何保存为pps自动播放格式ppt模板背景
- 用Swift语言开发SplitViewController范例
- ado.net事务
- leetcode_Move Zeroes
- Android实现button居中的方法
- 4种VPS主机技术原理及优缺点(VPS独享主机技术原理)
- AnimatorListener 里面的几种方法分别对应动画播放的一个事件
- TCP协议疑难杂症全景解析
- Android视频采集编码颜色格式选择
- 在美做开发多年,写给国内iphone新手,转自http://bbs.feng.com/read-htm-tid-768284.html
- excel操作类
- HDU 5445——Food Problem——————【多重背包】
- Windows传感器开发之请求用户许可
- openSUSE系统下VirtualBox无法挂载主机USB设备问题的解决
- 关于编译报错“dereferencing pointer to incomplete type...