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=200*200+10;
const int Maxn=200+10;
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=0; i<=N; i++) G[i].clear();
    memset(F,0,sizeof F);
    memset(Belong,0,sizeof Belong);
    for(int i=0; i<=N; i++) dis[i]=INF;
    nx=N,ny=N;
    memset(g,0,sizeof(g));
}

void SPFA()
{
    while(!Q.empty()) Q.pop();
    memset(flag,0,sizeof flag);
    flag[St]=1;
    dis[St]=0;
    Q.push(St);
    while(!Q.empty())
    {
        int h=Q.front();
        Q.pop();
        flag[h]=0;
        for(int i=0; i<G[h].size(); i++)
        {
            if(dis[h]+1<dis[G[h][i]])
            {
                dis[G[h][i]]=dis[h]+1;
                if(!flag[G[h][i]])
                {
                    flag[G[h][i]]=1;
                    Q.push(G[h][i]);
                }
            }
        }
    }
}

int path(int u)
{
    for(int v=1; v<=ny; v++)
    {
        if(g[u][v]&&!mk[v])
        {
            mk[v]=1;
            if(cy[v]==-1||path(cy[v]))
            {
                cx[u]=v;
                cy[v]=u;
                return 1;
            }
        }
    }
    return 0;
}

int MaxMatch()
{
    int res=0;
    memset(cx,-1,sizeof(cx));
    memset(cy,-1,sizeof(cy));
    for(int i=1; i<=nx; i++)
    {
        if(cx[i]==-1)
        {
            memset(mk,0,sizeof(mk));
            res=res+path(i);
        }
    }
    return res;
}

int main()
{
    while(~scanf("%d%d",&N,&M))
    {
        init();
        for(int i=1; i<=M; i++) scanf("%d%d",&U[i],&V[i]);
        for(int i=1; i<=M; i++)
        {
            G[U[i]].push_back(V[i]);
            G[V[i]].push_back(U[i]);
        }
        for(int i=1; i<=N; i++)
            if(dis[i]==INF) St=i,SPFA();
        for(int i=1; i<=N; i++)
        {
            if(dis[i]%2==0) Belong[i]=2;
            else Belong[i]=1;
        }
        int Fail=0;
        for(int i=1; i<=M; i++)
            if(Belong[U[i]]==Belong[V[i]])
            {
                Fail=1;
                break;
            }
        if(Fail==1) printf("No\n");
        else
        {
            for(int i=1; i<=M; i++)
            {
                if(Belong[U[i]]==1&&Belong[V[i]]==2)
                    g[U[i]][V[i]]=1;
                if(Belong[V[i]]==1&&Belong[U[i]]==2)
                    g[V[i]][U[i]]=1;
            }
            printf("%d\n",MaxMatch());
        }
    }
    return 0;
}

 

posted @ 2015-09-06 09:49  Fighting_Heart  阅读(171)  评论(0编辑  收藏  举报