Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 236 | Accepted: 98 |
Description
Input
Output
Sample Input
2 0: (1) 2 1: (1) 2 1 0: (1) 1
Sample Output
1 1
Hint
Source
Hopcroft_Carp算法时间复杂度是O(n^0.5*m)。
用Dinic算法求最大流比匹配更快。
Hopcroft_Carp代码:
#include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; const int N=10005; const int INF=1<<28; int Mx[N],My[N],Nx,Ny; int dx[N],dy[N],dis; vector<int> adj[N]; bool vst[N]; bool searchP() { queue<int> q; dis=INF; memset(dx,-1,sizeof(dx)); memset(dy,-1,sizeof(dy)); for(int i=0;i<Nx;i++) if(Mx[i]==-1) { q.push(i); dx[i]=0; } while(!q.empty()) { int u=q.front(),v; q.pop(); if(dx[u]>dis) break; for(int i=0;i<adj[u].size();i++) if(dy[v=adj[u][i]]==-1) { dy[v]=dx[u]+1; if(My[v]==-1) dis = dy[v]; else { dx[My[v]]=dy[v]+1; q.push(My[v]); } } } return dis!=INF; } bool dfs(int u) { int i,v; for(i=0;i<adj[u].size();i++) if(!vst[v=adj[u][i]]&&dy[v]==dx[u]+1) { vst[v]=1; if(My[v]!=-1&&dy[v]==dis) continue; if(My[v]==-1||dfs(My[v])) { My[v]=u; Mx[u]=v; return 1; } } return 0; } int MaxMatch()//O(n^0.5*m) { int ans=0; memset(Mx,-1,sizeof(Mx)); memset(My,-1,sizeof(My)); while(searchP()) { memset(vst,0,sizeof(vst)); for(int i=0;i<Nx;i++) if(Mx[i]==-1&&dfs(i)) ans++; } return ans; } int main() { int n,m,i,j,k; while(~scanf("%d",&n)) { for(i=0;i<n;i++) { scanf("%d: (%d)",&j,&m); adj[j].clear(); while(m--) { scanf("%d",&k); adj[j].push_back(k-n); } } Nx=Ny=n; printf("%d\n",MaxMatch()); } }
Dinic代码:
#include<cstdio> #include<cstring> #define N 20005 #define M 200005 #define inf 999999999 #define min(a,b) ((a)<(b)?(a):(b)) int n,m,s,t,num,adj[N],dis[N],q[N]; struct edge { int v,w,pre; }e[M]; void insert(int u,int v,int w) { e[num]=(edge){v,w,adj[u]}; adj[u]=num++; e[num]=(edge){u,0,adj[v]};//有向图 adj[v]=num++; } int bfs() { int i,x,v,head=0,tail=0; memset(dis,0,sizeof(dis)); dis[s]=1; q[++tail]=s; while(head!=tail) { x=q[head=(head+1)%N]; for(i=adj[x];~i;i=e[i].pre) if(e[i].w&&!dis[v=e[i].v]) { dis[v]=dis[x]+1; if(v==t) return 1; q[tail=(tail+1)%N]=v; } } return 0; } int dfs(int x,int limit) { if(x==t) return limit; int i,v,tmp,cost=0; for(i=adj[x];~i&&cost<limit;i=e[i].pre) if(e[i].w&&dis[x]==dis[v=e[i].v]-1) { tmp=dfs(v,min(limit-cost,e[i].w)); if(tmp) { e[i].w-=tmp; e[i^1].w+=tmp; cost+=tmp; } else dis[v]=-1; } return cost; } int Dinic() { int ans=0; while(bfs()) ans+=dfs(s,inf); return ans; } int main() { while(~scanf("%d",&n)) { int i,j,k; memset(adj,-1,sizeof(adj)); num=0; s=0; t=n+n+1; for(i=0;i<n;i++) { scanf("%d: (%d)",&j,&m); while(m--) { scanf("%d",&k); insert(j+1,k+1,1); } } for(i=1;i<=n;i++) { insert(s,i,1); insert(i+n,t,1); } printf("%d\n",Dinic()); } }