P2417 课程
裸地匈牙利算法,
贪心的不断匹配,若没匹配,则匹配;反之,判断与之匹配的点能否在找另一个点匹配,若能,抢多这个点与之匹配
时间复杂度$O(n imes m)$
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define N 2000000 using namespace std; struct node{ int to,next; }e[N]; int t,head[N],tot,p,n,match[N],dfn[N],ans; void add(int u,int v){ e[++tot].to=v,e[tot].next=head[u],head[u]=tot; } bool dfs(int u,int t){ for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(dfn[v]!=t){ dfn[v]=t; if(!match[v]||dfs(match[v],t)){ match[v]=u;return true; } } } return false; } int main() { scanf("%d",&t); while(t--){ memset(head,0,sizeof(head)); memset(match,0,sizeof(match)); memset(dfn,0,sizeof(dfn)); tot=ans=0; scanf("%d%d",&p,&n); for(int m,v,i=1;i<=p;i++){ scanf("%d",&m); for(int j=1;j<=m;j++){ scanf("%d",&v),add(v,i); } } for(int i=1;i<=n;i++) if(dfs(i,i)) ++ans; if(ans>=p) printf("YES "); else printf("NO "); } return 0; }
P2071 座位安排
模板,又是模板,建图方式有一点儿不同,因为每一排有两个座位
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define N 2000000 using namespace std; struct node { int to,next; } e[N]; int t,head[N],tot,p,n,match[N],dfn[N],ans; void add(int u,int v) { e[++tot].to=v,e[tot].next=head[u],head[u]=tot; } bool dfs(int u,int t) { for(int i=head[u]; i; i=e[i].next) { int v=e[i].to; if(dfn[v]!=t) { dfn[v]=t; if(!match[v]||dfs(match[v],t)) { match[v]=u; return true; } } } return false; } int main() { memset(head,0,sizeof(head)); memset(match,0,sizeof(match)); memset(dfn,0,sizeof(dfn)); tot=ans=0; scanf("%d",&n); for(int x,y,i=1; i<=n*2; i++) { scanf("%d%d",&x,&y); add(i,x),add(i,x+n),add(i,y),add(i,y+n); } for(int i=1; i<=n*2; i++) if(dfs(i,i)) ++ans; printf("%d ",ans); return 0; }
P1894 [USACO4.2]完美的牛栏The Perfect Stall
裸题
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define N 2000000 using namespace std; struct node { int to,next; } e[N]; int t,head[N],tot,m,n,match[N],dfn[N],ans; void add(int u,int v) { e[++tot].to=v,e[tot].next=head[u],head[u]=tot; } bool dfs(int u,int t) { for(int i=head[u]; i; i=e[i].next) { int v=e[i].to; if(dfn[v]!=t) { dfn[v]=t; if(!match[v]||dfs(match[v],t)) { match[v]=u; return true; } } } return false; } int main() { memset(head,0,sizeof(head)); memset(match,0,sizeof(match)); memset(dfn,0,sizeof(dfn)); tot=ans=0; scanf("%d%d",&n,&m); for(int v,x,i=1; i<=n; i++) { scanf("%d",&x); for(int j=1;j<=x;j++) { scanf("%d",&v); add(i,v); } } for(int i=1; i<=n; i++) if(dfs(i,i)) ++ans; printf("%d ",ans); return 0; }