hdu 3081&hdu 3277 (最大流)
来源:互联网 发布:焦土抗战 知乎 编辑:程序博客网 时间:2024/04/27 03:34
hdu 3081题意:n个女孩,n个男孩,每个女孩有自己喜欢的男孩,她也会喜欢自己朋友喜欢的男孩,朋友间的关系是可以传递的。每个女孩每轮游戏要找一个喜欢的男孩过家家。问游戏最多能玩多少轮。
hdu 3277:跟3081题目意思大概一样,就是加了一个每个女孩可以选k个自己不喜欢的男孩。
hdu 3081:思路:图是二分图,如果把每个女孩跟喜欢的男孩连边,建设能玩D轮游戏,就是该图的最大流是D*n了,所以加上源点汇点,再二分找出最大的游戏论数。
hdu 3277:在一题上把女孩拆成两个点,拆出来的点连接不喜欢的男孩,在二分建图时不能太复杂,不然得TLE。
hdu 3081:
#include<stdio.h>#include<string.h>const int N=300;const int inf=0x3fffffff;int head[N],num,gap[N],dis[N],first[N],tot,f[N],start,end,ans,n;bool map[110][110];struct edge{ int st,ed,flow,next;}e[N*10000];struct node{ int ed,next;}E[N*N];int find(int a){ if(a!=f[a]) f[a]=find(f[a]); return f[a];}void addedge(int x,int y,int w){ e[num].ed=y;e[num].flow=w;e[num].next=head[x];head[x]=num++; e[num].ed=x;e[num].flow=0;e[num].next=head[y];head[y]=num++;}void Addedge(int x,int y){ E[tot].ed=y;E[tot].next=first[x];first[x]=tot++;}int dfs(int u,int minflow) { if(u==end)return minflow; int i,v,f,min_dis=ans-1,flow=0; for(i=head[u];i!=-1;i=e[i].next) { v=e[i].ed; if(e[i].flow<=0)continue; if(dis[v]+1==dis[u]) { f=dfs(v,e[i].flow>minflow-flow?minflow-flow:e[i].flow); e[i].flow-=f; e[i^1].flow+=f; flow+=f; if(flow==minflow)break; if(dis[start]>=ans)return flow; } min_dis=min_dis>dis[v]?dis[v]:min_dis; } if(flow==0) { if(--gap[dis[u]]==0) dis[start]=ans; dis[u]=min_dis+1; gap[dis[u]]++; } return flow; }int isap(){ int maxflow=0; memset(gap,0,sizeof(gap)); memset(dis,0,sizeof(dis)); gap[0]=ans; while(dis[start]<ans) maxflow+=dfs(start,inf); return maxflow;}bool judge(int D){ memset(head,-1,sizeof(head)); num=0; int i,j; for(i=1;i<=n;i++){addedge(start,i,D);addedge(i+n,end,D);for(j=1;j<=n;j++){if(map[i][j])addedge(i,j+n,1);}} if(isap()==n*D) return true; return false;}int main(){ int i,j,k,m,F,t,x,y,flag; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&F); tot=0;start=0;end=n+n+1;ans=end+1; memset(first,-1,sizeof(first));memset(map,false,sizeof(map)); for(i=1;i<=n;i++) f[i]=i; for(i=0;i<m;i++) { scanf("%d%d",&x,&y); Addedge(x,y);map[x][y]=true; } while(F--) { scanf("%d%d",&x,&y); if(find(x)!=find(y))f[find(x)]=find(y); }for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(find(i)!=find(j))continue; for(k=first[i];k!=-1;k=E[k].next) map[j][E[k].ed]=true; for(k=first[j];k!=-1;k=E[k].next) map[i][E[k].ed]=true; } } int L=0,R=n,mid; flag=0; while(L<=R) { mid=(L+R)>>1; if(judge(mid)) { flag=mid; L=mid+1; } else R=mid-1; } printf("%d\n",flag); } return 0;}
hdu 3277:
#include<stdio.h>#include<string.h>const int N=1000;const int inf=0x3fffffff;int head[N],num,gap[N],dis[N],first[N],tot,f[N],start,end,ans,n,K;bool map[300][300];struct edge{ int st,ed,flow,next;}e[N*1000];struct node{ int ed,next;}E[N*N];int find(int a){ if(a!=f[a]) f[a]=find(f[a]); return f[a];}void addedge(int x,int y,int w){ e[num].ed=y;e[num].flow=w;e[num].next=head[x];head[x]=num++; e[num].ed=x;e[num].flow=0;e[num].next=head[y];head[y]=num++;}void Addedge(int x,int y){ E[tot].ed=y;E[tot].next=first[x];first[x]=tot++;}int dfs(int u,int minflow) { if(u==end)return minflow; int i,v,f,min_dis=ans-1,flow=0; for(i=head[u];i!=-1;i=e[i].next) { v=e[i].ed; if(e[i].flow<=0)continue; if(dis[v]+1==dis[u]) { f=dfs(v,e[i].flow>minflow-flow?minflow-flow:e[i].flow); e[i].flow-=f; e[i^1].flow+=f; flow+=f; if(flow==minflow)break; if(dis[start]>=ans)return flow; } min_dis=min_dis>dis[v]?dis[v]:min_dis; } if(flow==0) { if(--gap[dis[u]]==0) dis[start]=ans; dis[u]=min_dis+1; gap[dis[u]]++; } return flow; }int isap(){ int maxflow=0; memset(gap,0,sizeof(gap)); memset(dis,0,sizeof(dis)); gap[0]=ans; while(dis[start]<ans) maxflow+=dfs(start,inf); return maxflow;}bool judge(int D){ memset(head,-1,sizeof(head)); num=0; int i,j; for(i=1;i<=n;i++) { addedge(start,i,D); addedge(i+n,end,D); addedge(i,i+2*n,K); for(j=1;j<=n;j++) { if(map[i][j]) addedge(i,j+n,1); else addedge(i+2*n,j+n,1); } } if(isap()==n*D) return true; return false;}int main(){ int i,j,k,m,F,t,x,y,flag; scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&n,&m,&K,&F); tot=0;start=0;end=n+n+n+1;ans=end+1; memset(first,-1,sizeof(first)); memset(map,false,sizeof(map)); for(i=1;i<=n;i++) f[i]=i; for(i=0;i<m;i++) { scanf("%d%d",&x,&y); Addedge(x,y); map[x][y]=true; } while(F--) { scanf("%d%d",&x,&y); if(find(x)!=find(y)) f[find(x)]=find(y); } for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(find(i)!=find(j))continue; for(k=first[i];k!=-1;k=E[k].next) map[j][E[k].ed]=true; for(k=first[j];k!=-1;k=E[k].next) map[i][E[k].ed]=true; } } int L=1,R=n,mid; flag=0; while(L<=R) { mid=(L+R)>>1; if(judge(mid)) { flag=mid; L=mid+1; } else R=mid-1; } printf("%d\n",flag); } return 0;}
- hdu 3081&hdu 3277 (最大流)
- hdu 3081 (最大流)
- hdu 3081 二分+最大流
- hdu 3081 二分+最大流
- hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //最大流的灵活运用
- hdu 2883(最大流)
- 【最大流】HDU 3572
- hdu 2883 最大流
- hdu 3572最大流
- hdu 3605 最大流
- HDU 1733 最大流
- hdu 3549 最大流
- hdu 2732 最大流
- hdu 3605 (最大流)
- hdu 2883 (最大流)
- hdu 3549 最大流
- hdu 1273最大流
- HDU 3549 (最大流)
- Kprobes源码分析----kprobe的注册
- 【使用JSOUP实现网络爬虫】从元素抽取属性,文本和HTML
- Linux下Openssl的安装全过程
- dll中启动shellcode卸载自身dll模块
- 转一篇杂谈:技术真的就不是那么重要了
- hdu 3081&hdu 3277 (最大流)
- lxc的安装--------------绝对正版
- Epoll实现原理解析
- Jquery EasyUI 异步树
- IOS之同步请求、异步请求、GET请求、POST请求
- Python set模块使用方法
- OPENGL|ES第五天,Adjusting to the Screen’s Aspect Ratio
- ActionScript 类库总结
- 嵌入式指导---项目设计流程