#include<cstdio> #define MAXM 1000005 #define MAXN 1005 #define MAXQ 1005 usingnamespacestd; int g[MAXM]; //Graph array int fst[MAXN]={0},nxt[MAXM]={0}; //Fore list int prev[MAXN]={0}; //prev means the last vertex which wanted to match int ans=0; //Ans means the count of matching edges int match[MAXN]={0}; //Match (A->B) int invmatch[MAXN]={0}; //Match (B->A) int que[MAXN]; //Don't use std::queue! It's slow. int visited[MAXN]; //Only for vertexes in B int unable_stack[MAXN]={0}; //Store the vertexes (in B) which are going to be unable voidhungarian(int x); intmain(void){ int n,m,e; scanf("%d%d%d",&n,&m,&e); for (int i=0;i<e;i++){ int u,v; int edge_num=i+1; scanf("%d%d",&u,&v); if (v>m) continue; //According to the tips //Only connect edges from A to B g[edge_num]=v; nxt[edge_num]=fst[u]; fst[u]=edge_num; } for (int i=1;i<=n;i++) if (!match[i]) //i hasn't found a vertex to match with hungarian(i); printf("%d\n",ans); return0; }
voidhungarian(int x){ int head,tail,st; //Queue head, queue tail, stack top head=tail=0; que[tail++]=x; //Notice: every vertex in que is in A prev[x]=0; //Prev means the vertex which asks i to change its matching vertex st=0; while (head!=tail){ //!q.empty() int nowv=que[head++]; //nowv means the current vertex which wants to change its matching vertex if (head==MAXQ) head=0; //Cycling queue for (int i=fst[nowv];i;i=nxt[i]){ if (visited[g[i]]==-1 || visited[g[i]]==x) //The visited array is similar to the "inq" tag //visited[x]==-1 means it can't be replaced continue; unable_stack[st++]=g[i]; //Push g[i] to the stack //If this match fails, visited[g[i]] will be set to -1 visited[g[i]]=x; //Notice: the index of visited means vertexes in B if (!invmatch[g[i]]){ //If g[i] isn't a matching vertex int nowv_to_match=g[i]; int prev_to_match; ans++; //Find a new matching edge while (nowv){ //Go back in order to update the matching vertexes prev_to_match=match[nowv]; match[nowv]=nowv_to_match; invmatch[nowv_to_match]=nowv; nowv=prev[nowv]; nowv_to_match=prev_to_match; } //Match successfully, return return; } //Ask invmatch[g[i]] (the vertex which matches with g[i]) to change its matching vertex que[tail++]=invmatch[g[i]]; prev[invmatch[g[i]]]=nowv; //Set down the prev if (tail==MAXQ) tail=0; } } //Match failed //Set the visited value of all the vertexes which I have asked to change to -1 while (st){ st--; visited[unable_stack[st]]=-1; } }
#include<cstdio> #define MAXM 1000005 #define MAXN 1005 usingnamespacestd; int g[MAXM]; //Graph array int fst[MAXN]={0},nxt[MAXM]={0}; //Fore list int ans=0; //Ans means the count of matching edges int rnd=0; //Means the round of dfs int match[MAXN]={0}; //Match (A->B) int invmatch[MAXN]={0}; //Match (B->A) int visited[MAXN]; //Only for vertexes in B inthungarian(int x); intmain(void){ int n,m,e; scanf("%d%d%d",&n,&m,&e); for (int i=0;i<e;i++){ int u,v; int edge_num=i+1; scanf("%d%d",&u,&v); if (v>m) continue; //According to the tips //Only connect edges from A to B g[edge_num]=v; nxt[edge_num]=fst[u]; fst[u]=edge_num; } for (int i=1;i<=n;i++){ if (!match[i]){ //i hasn't found a vertex to match with rnd=i; if (hungarian(i)) ans++; } } printf("%d\n",ans); return0; }
inthungarian(int x){ for (int i=fst[x];i;i=nxt[i]){ if (visited[g[i]]==-1 || visited[g[i]]==rnd) //The visited array is similar to the "inq" tag //visited[x]==-1 means it can't be replaced continue; visited[g[i]]=rnd; //Notice: the index of visited means vertexes in B if (!invmatch[g[i]] || hungarian(invmatch[g[i]])){ //If g[i] isn't a matching vertex or its matching vertex has successfully changed match[x]=g[i]; invmatch[g[i]]=x; return1; } } //Match failed //Set the visited of match[x] to -1 if (match[x]) visited[match[x]]=-1; return0; }