HDU 2444 The Accomodation of Students

时间:2023-03-09 09:30:50
HDU 2444 The Accomodation of Students

首先是要构造二分图,然后二分图的最大匹配。

还有没完全证明过我的方法的正确性,但是AC了.....

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std; const int INF=0x7FFFFFFF;
const int maxn=*+;
const int Maxn=+;
int N,M;
int U[maxn],V[maxn];
int F[Maxn];
vector<int>G[Maxn];
int St;
int dis[Maxn],flag[Maxn];
queue<int>Q;
int Belong[Maxn]; int nx,ny;
int g[Maxn][Maxn];
int cx[Maxn],cy[Maxn];
int mk[Maxn]; void init()
{
for(int i=; i<=N; i++) G[i].clear();
memset(F,,sizeof F);
memset(Belong,,sizeof Belong);
for(int i=; i<=N; i++) dis[i]=INF;
nx=N,ny=N;
memset(g,,sizeof(g));
} void SPFA()
{
while(!Q.empty()) Q.pop();
memset(flag,,sizeof flag);
flag[St]=;
dis[St]=;
Q.push(St);
while(!Q.empty())
{
int h=Q.front();
Q.pop();
flag[h]=;
for(int i=; i<G[h].size(); i++)
{
if(dis[h]+<dis[G[h][i]])
{
dis[G[h][i]]=dis[h]+;
if(!flag[G[h][i]])
{
flag[G[h][i]]=;
Q.push(G[h][i]);
}
}
}
}
} int path(int u)
{
for(int v=; v<=ny; v++)
{
if(g[u][v]&&!mk[v])
{
mk[v]=;
if(cy[v]==-||path(cy[v]))
{
cx[u]=v;
cy[v]=u;
return ;
}
}
}
return ;
} int MaxMatch()
{
int res=;
memset(cx,-,sizeof(cx));
memset(cy,-,sizeof(cy));
for(int i=; i<=nx; i++)
{
if(cx[i]==-)
{
memset(mk,,sizeof(mk));
res=res+path(i);
}
}
return res;
} int main()
{
while(~scanf("%d%d",&N,&M))
{
init();
for(int i=; i<=M; i++) scanf("%d%d",&U[i],&V[i]);
for(int i=; i<=M; i++)
{
G[U[i]].push_back(V[i]);
G[V[i]].push_back(U[i]);
}
for(int i=; i<=N; i++)
if(dis[i]==INF) St=i,SPFA();
for(int i=; i<=N; i++)
{
if(dis[i]%==) Belong[i]=;
else Belong[i]=;
}
int Fail=;
for(int i=; i<=M; i++)
if(Belong[U[i]]==Belong[V[i]])
{
Fail=;
break;
}
if(Fail==) printf("No\n");
else
{
for(int i=; i<=M; i++)
{
if(Belong[U[i]]==&&Belong[V[i]]==)
g[U[i]][V[i]]=;
if(Belong[V[i]]==&&Belong[U[i]]==)
g[V[i]][U[i]]=;
}
printf("%d\n",MaxMatch());
}
}
return ;
}