nyoj 月老的难题
来源:互联网 发布:幼年秦义绝捏脸数据 编辑:程序博客网 时间:2024/04/29 20:30
http://acm.nyist.net/JudgeOnline/problem.php?pid=239
此题为二分最大匹配入门之必备习题之一!
话不多,上代码~
代码1:邻接表+匈牙利算法(邻接矩阵貌似会tle,此题数据量较大)
#include<stdio.h> #include<stdlib.h> #include<string.h> struct EdgeNode { int adjvex; struct EdgeNode *next; }; struct VexNode { struct EdgeNode *firstedge; }; struct VexNode alist[510]; int visit[501],match[510]; int find(int x) { <span style="white-space:pre"></span>int k; <span style="white-space:pre"></span>struct EdgeNode *p; <span style="white-space:pre"></span>p=alist[x].firstedge; <span style="white-space:pre"></span>while (p) <span style="white-space:pre"></span>{ <span style="white-space:pre"></span>k=p->adjvex; <span style="white-space:pre"></span>if (!visit[k]) <span style="white-space:pre"></span>{<span style="white-space:pre"></span>visit[k]=1; <span style="white-space:pre"></span>if (!match[k]||find(match[k])) <span style="white-space:pre"></span>{ <span style="white-space:pre"></span>match[k]=x; <span style="white-space:pre"></span>return 1; <span style="white-space:pre"></span>}<span style="white-space:pre"></span>} <span style="white-space:pre"></span>p=p->next; <span style="white-space:pre"></span>} <span style="white-space:pre"></span>return 0; } int main() { <span style="white-space:pre"></span>int n,t,k,i,ans,vi,vj; <span style="white-space:pre"></span>struct EdgeNode *s; <span style="white-space:pre"></span>scanf("%d",&t); <span style="white-space:pre"></span>while (t--) <span style="white-space:pre"></span> <span style="white-space:pre"></span>{ <span style="white-space:pre"></span>scanf("%d%d",&n,&k); <span style="white-space:pre"></span>memset(alist,0,sizeof(alist)); <span style="white-space:pre"></span>memset(match,0,sizeof(match)); <span style="white-space:pre"></span>for (i=1;i<=k;i++) <span style="white-space:pre"></span>{ <span style="white-space:pre"></span>scanf("%d%d",&vi,&vj); <span style="white-space:pre"></span>s=(struct EdgeNode*)malloc(sizeof(struct EdgeNode)); <span style="white-space:pre"></span>s->adjvex=vj; <span style="white-space:pre"></span>s->next=alist[vi].firstedge; <span style="white-space:pre"></span>alist[vi].firstedge=s; <span style="white-space:pre"></span>} <span style="white-space:pre"></span>for (i=1,ans=0;i<=n;i++) <span style="white-space:pre"></span>{ <span style="white-space:pre"></span>memset(visit,0,sizeof(visit)); <span style="white-space:pre"></span>if (find(i)) ans++; <span style="white-space:pre"></span> <span style="white-space:pre"></span>} <span style="white-space:pre"></span>printf("%d\n",ans); <span style="white-space:pre"></span>} <span style="white-space:pre"></span>return 0; }
</pre><pre name="code" class="cpp"><img src="http://img.blog.csdn.net/20140807152147938?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQVExNEFRMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
</pre><pre name="code" class="cpp">
代码2:最大流
思路:在原二分图的基础上,做几点修改,增加一个超级源点,并把源点和集合U(设二分图的点为两个集合U和V)中的每个点连成有向边,容量为1,再增加一个超级汇点,并把集合V中的每个点于汇点连成有向边,容量为1。
#include<iostream>using namespace std;#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#define MAXM 30010 #define MAXN 1010#define oo 0x7fffffffstruct Dinic { struct node { int x,y,c,next; }line[MAXM]; int Lnum,_next[MAXN],dis[MAXN]; void initial(int n) { for (int i=0;i<=n;i++) _next[i]=-1; Lnum=-1; } void addline(int x,int y,int c) { line[++Lnum].next=_next[x],_next[x]=Lnum; line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c; line[++Lnum].next=_next[y],_next[y]=Lnum; line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0; } int BFS(int s,int e) { queue<int> Q; while (!Q.empty()) Q.pop(); memset(dis,-1,sizeof(dis)); dis[s]=0; Q.push(s); while (!Q.empty()) { int h,k; h=Q.front(),Q.pop(); if (h==e) return dis[e]; for (k=_next[h];k!=-1;k=line[k].next) if (line[k].c && dis[line[k].y]==-1) dis[line[k].y]=dis[h]+1,Q.push(line[k].y); } return false; } int dfs(int x,int flow,int e) { if (x==e) return flow; int temp,cost=0; for (int k=_next[x];k!=-1;k=line[k].next) if (line[k].c && dis[line[k].y]==dis[x]+1) { temp=dfs(line[k].y,min(flow-cost,line[k].c),e); if (temp) { line[k].c-=temp,line[k^1].c+=temp; cost+=temp; if (flow==cost) return cost; }else dis[line[k].y]=0; } return cost; } int MaxFlow(int s,int e) { int MaxFlow=0; while (BFS(s,e)) MaxFlow+=dfs(s,oo,e); return MaxFlow; } }T; int main(){ int t; scanf("%d",&t); while (t--) { int n,k; scanf("%d%d",&n,&k); int N=2*n+1; T.initial(N); int v1[501],v2[501]; memset(v1,0,sizeof(v1)); memset(v2,0,sizeof(v2)); for (int i=0;i<k;++i) { int u,v; scanf("%d%d",&u,&v); T.addline(u,v+n,1); if (v1[u]==0) { v1[u]=1; T.addline(0,u,1); } if (v2[v]==0) { v2[v]=1; T.addline(v+n,N,1); } } int ans=T.MaxFlow(0,N); printf("%d\n",ans); } return 0;} #include<iostream>using namespace std;#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#define MAXM 30010 #define MAXN 1010#define oo 0x7fffffffstruct Dinic { struct node { int x,y,c,next; }line[MAXM]; int Lnum,_next[MAXN],dis[MAXN]; void initial(int n) { for (int i=0;i<=n;i++) _next[i]=-1; Lnum=-1; } void addline(int x,int y,int c) { line[++Lnum].next=_next[x],_next[x]=Lnum; line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c; line[++Lnum].next=_next[y],_next[y]=Lnum; line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0; } int BFS(int s,int e) { queue<int> Q; while (!Q.empty()) Q.pop(); memset(dis,-1,sizeof(dis)); dis[s]=0; Q.push(s); while (!Q.empty()) { int h,k; h=Q.front(),Q.pop(); if (h==e) return dis[e]; for (k=_next[h];k!=-1;k=line[k].next) if (line[k].c && dis[line[k].y]==-1) dis[line[k].y]=dis[h]+1,Q.push(line[k].y); } return false; } int dfs(int x,int flow,int e) { if (x==e) return flow; int temp,cost=0; for (int k=_next[x];k!=-1;k=line[k].next) if (line[k].c && dis[line[k].y]==dis[x]+1) { temp=dfs(line[k].y,min(flow-cost,line[k].c),e); if (temp) { line[k].c-=temp,line[k^1].c+=temp; cost+=temp; if (flow==cost) return cost; }else dis[line[k].y]=0; } return cost; } int MaxFlow(int s,int e) { int MaxFlow=0; while (BFS(s,e)) MaxFlow+=dfs(s,oo,e); return MaxFlow; } }T; int main(){ int t; scanf("%d",&t); while (t--) { int n,k; scanf("%d%d",&n,&k); int N=2*n+1; T.initial(N); int v1[501],v2[501]; memset(v1,0,sizeof(v1)); memset(v2,0,sizeof(v2)); for (int i=0;i<k;++i) { int u,v; scanf("%d%d",&u,&v); T.addline(u,v+n,1); if (v1[u]==0) { v1[u]=1; T.addline(0,u,1); } if (v2[v]==0) { v2[v]=1; T.addline(v+n,N,1); } } int ans=T.MaxFlow(0,N); printf("%d\n",ans); } return 0;}
0 0
- nyoj 月老的难题
- nyoj 月老的难题
- NYOJ-239 月老的难题
- NYOJ 239 月老的难题
- NYOJ 239 月老的难题
- NYOJ 239-月老的难题
- nyoj 239 月老的难题
- NYOJ-239 月老的难题
- nyoj 239 月老的难题
- NYOJ 月老的难题南工478
- 存模版 nyoj 239 月老的难题
- nyoj 月老的难题【最大匹配】
- NYOJ 月老的难题和游戏高手的烦恼
- NYOJ 239 月老的难题(二分图匹配)
- NYOJ 478 月老的难题 (1)解题报告
- NYOJ 239 月老的难题 (深度优先遍历)
- NYOJ 239 月老的难题(二分图最大匹配)
- nyoj 239 月老的难题 【二分匹配之匈牙利】
- X86架构下Linux启动过程分析
- 面向对象10原则
- 点击单选按钮后的文字即可选定对应单选按钮
- 华为机试总结(一)字符串过滤、压缩
- __declspec,__cdecl,__stdcall,__declspec
- nyoj 月老的难题
- oc 常用字符串操作
- 什么pdf转换成word转换器在线好
- Socket编程中的强制关闭与优雅关闭及相关socket选项
- ZooKeeper API 的使用
- 10岁男孩不服父亲打骂管教方式 10次离家出走
- 用rand和srand产生某两个数之间的随机数
- 关于 overridePendingTransition()使用
- 图论500题