[HNOI2006]超级英雄 网络流+二分版
刚学网络流的我这里有一道非常好的"网络流练手题"------[HNOI2006]超级英雄.
记得很久以前真的有这个节目来着,还是大兵主持的.
其实这是一道匈牙利板子大水题,但对于我们这种刚学网络流的 juruo 碰到什么题不用网络流做就非常的不爽,于是就有了这个 超级英雄 网络流+二分版.
这里直接二分答案,每次将源点和所有的锦囊连边,容量为1;再将锦囊和对应的问题连边,容量为1;最后是将问题和汇点T连边,容量还是1.然后跑一波Dinic,看是否满流,这道"网络流练手题就搞定了".
最后再吐槽一下:这道题的网络流打法非常非常优秀(比匈牙利慢而且代码量翻倍),没事干的时候可以打着玩儿......
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define inf (1<<30) #define maxn (300050) #define maxm (300050) #define ll long long #define il inline #define RG register using namespace std; il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while( ( ch<'0' || ch>'9' ) && ch!='-' ) ch=getchar(); if( ch=='-' ) q=-1,ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; } int S,T,n,m,num=1,F,que[maxn*5],level[maxn]; struct data{ int a,b; }ques[maxn]; int head[maxn],nxt[maxm],to[maxm],w[maxm]; il void add( int u,int v,int d ){ nxt[++num]=head[u];to[num]=v;w[num]=d;head[u]=num; nxt[++num]=head[v];to[num]=u;w[num]=0;head[v]=num; } il bool bfs(){ for(int i=S;i<=T;i++) level[i]=0; que[0]=S,level[S]=1; RG int hd=0,tl=1; while(hd<tl){ RG int x=que[hd++]; if(x==T) return true; for(int i=head[x];i;i=nxt[i]){ RG int v=to[i]; if(w[i] && !level[v]){ level[v]=level[x]+1; que[tl++]=v; } } } return false; } il int dfs(RG int x,RG int maxf){ if(x==T) return maxf; RG int ans=0; for(RG int i=head[x];i;i=nxt[i]){ RG int v=to[i],f=w[i]; if(level[v]==level[x]+1 && f){ RG int minn=min(f,maxf-ans); f=dfs(v,minn); w[i]-=f,w[i^1]+=f,ans+=f; if(ans==maxf) break; } } if(!ans) level[x]=0; return ans; } il void Dinic(){ while(bfs()) F+=dfs(S,inf); } il bool check(int mid){ memset(head,0,sizeof(head)); num=1; F=0; for(int i=1;i<=n;i++) add(S,i,1); for(int i=1;i<=mid;i++){ add(ques[i].a,i+n,1); add(ques[i].b,i+n,1); add(i+n,T,1); } Dinic(); if(F>=mid) return 1; else return 0; } il void init(){ n=gi(),m=gi();S=0,T=n+m+1; for(int i=1;i<=m;i++) ques[i].a=gi()+1,ques[i].b=gi()+1; } il void work(){ int l=0,r=m,ans=0; while(l<=r){ RG int mid=(l+r)>>1; if( check(mid) ) l=mid+1,ans=mid; else r=mid-1; } printf("%d\n",ans); } int main(){ init(); work(); return 0; }
最后顺便再附上匈牙利版代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int map[1001][1001],club[1001]; int n,m; bool vis[1001]; bool dfs(int x){ for(int i=0;i<n;i++) if(!vis[i]&&map[x][i]){ vis[i]=1; if( !club[i]||dfs(club[i]) ){ club[i]=x; return true; } } return false; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int x,y; scanf("%d%d",&x,&y); map[i][x]=map[i][y]=1; } int ans=0; for(int i=1;i<=m;i++){ memset(vis,0,sizeof(vis)); if(dfs(i))ans++; else break; } printf("%d\n",ans); return 0; }
[HNOI2006]超级英雄 网络流+二分版的更多相关文章
- [HNOI2006]超级英雄(二分+网络流)
[HNOI2006]超级英雄 题目描述 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金.主持人问题准备了若干道题目, ...
- BZOJ 1191: [HNOI2006]超级英雄Hero 二分匹配
1191: [HNOI2006]超级英雄Hero Description 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或 ...
- BZOJ 1191: [HNOI2006]超级英雄Hero(二分图匹配)
云神说他二分图匹配从来都是用网络流水过去的...我要发扬他的精神.. 这道题明显是二分图匹配.网络流的话可以二分答案+最大流.虽然跑得很慢.... -------------------------- ...
- bzoj 1191: [HNOI2006]超级英雄Hero
1191: [HNOI2006]超级英雄Hero Time Limit: 10 Sec Memory Limit: 162 MB 二分图匹配... Description 现在电视台有一种节目叫做超 ...
- bzoj 1191: [HNOI2006]超级英雄Hero 并查集 || 匈牙利算法
1191: [HNOI2006]超级英雄Hero Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1804 Solved: 850[Submit][S ...
- bzoj 1191 [HNOI2006]超级英雄Hero(最大基数匹配)
1191: [HNOI2006]超级英雄Hero Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2813 Solved: 1331[Submit][ ...
- POJ Secret Milking Machine 【网络流+二分】
题意:各一个地图,两点之间有若干条路,要在节点1和节点n之间行走t次(就是问1到n的路径数至少为t,每一条路径不能有重复),问所有路径里面最长的部分(这个题目特别强调,不是路径长度和,是路径中相邻两点 ...
- 1191: [HNOI2006]超级英雄Hero
1191: [HNOI2006]超级英雄Hero Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1996 Solved: 946[Submit][S ...
- [luogu P2319] [HNOI2006]超级英雄
[luogu P2319] [HNOI2006]超级英雄 题目描述 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金. ...
随机推荐
- Java基础——多态
多态性是指允许不同类型的对象对同一消息做出相应.具有灵活性.抽象.行为共享.代码共享的优势,共享就意味着最大化利用和简洁,还有就是加载速度. 一.多态的作用 消除类型之间的耦合关系.即同一事件发生在不 ...
- TestNG+ExtentReports生成超漂亮的测试报告
一个优雅.漂亮的测试报告,能够给我们的测试工作带来不少的加分,而报告的模版实在是让我们这些技术人员头疼的问题,设计的实在是没有什么美感. 那么今天就给大家分享一个自动化测试中,一个超漂亮的测试报告模版 ...
- Linux命令 查看文件内容
cat [功能说明] 查看文件的内容 #cat本身是一个串接命令,把指定一个或多个源文件的内容,利用>符号重定向到目标文件中,如果不指定重定向文件,则默认在标准输出设备上显示.此时,可以利用c ...
- 通过bin-log对mysql进行数据恢复
mysqlbinlog --database=数据库名 --start-date="2017-06-01 5:00:00" --stop-date="2017-06-1 ...
- java 二叉树实现
//二叉树,有左子数,右子树,小的值放到左边,大的值放到右边,左边有树的话继续这个过程,(以下为代部分,赋值的时候采用了递归的方式) package liaobiao;class BiTree{ pr ...
- Mac, Linux中配置Latex中文字体
对于中文的latex文档,在Linux下一般可以使用系统自带的开源字体:文泉驿(WenQuanYi)来实现,即如下的最小例子,通过xelatex命令来编译即可生成中文文档. \documentclas ...
- el 表达式遍历Map
el 表达式遍历Map<c:forEach var="item" items="${payMentMap}"> <option value=& ...
- PHP加密解密数字
<?php /** * 加密解密类,PHP加密解密数字,适用于URL加密 * 该算法仅支持加密数字.比较适用于数据库中id字段的加密解密,以及根据数字显示url的加密. * @version a ...
- Swift计算字符数量
通过调用全局 countElements 函数并将字符串作为参数进行传递可以获取该字符串的字符数量. let unusualMenagerie = "Koala
- 4.vbs的循环,switch,判断等语句
1.条件判断语句 If Then Else Sub judge(x) Then MsgBox "the num is 0" Then MsgBox "the num is ...