读书人

hdu 3225 Flowers Placement 二分图婚

发布时间: 2013-10-18 20:53:13 作者: rapoo

hdu 3225 Flowers Placement 二分图匹配+dfs

回来再写题解,上课去。。


#include <iostream>#include <cstdio>#include <algorithm>#define maxn 300005#define lson num<<1,s,mid#define rson num<<1|1,mid+1,e#include<cstdio>#include<cstring>#include<vector>using namespace std;#define N 205bool vis[N];vector<int> g[N];int maps[N];  //始终保存完备匹配的方案。int ans[205];int top,tot;int n,m,k;int use[205];int save[205];int find(int k,int st)  //找 从st+1——n是否能构成完备匹配{    if(k<=st) return 0;    for(int i=0;i<g[k].size();i++)    {        int boy=g[k][i];        if(!vis[boy])        {            vis[boy]=1;            if(maps[boy]==0||find(maps[boy],st))            {                maps[boy]=k;                return 1;            }        }    }    return 0;}bool isok(int now,int flo)   //假设now位置放flo花{    if(maps[flo]==now) return true;    int j;    for(int i=1;i<=n;i++)    {        save[i]=maps[i];        vis[i]=0;        if(maps[i]==now) j=i;   //找到上一次完备匹配now位置放的花    }    int t=maps[flo];                    //断开匹配    maps[flo]=now;    //修改匹配    maps[j]=0;    if(find(t,now)) return true;    //从now+1——n之间再次为t找一个匹配    else                            //没找到,则回溯    {        for(int i=1;i<=n;i++)            maps[i]=save[i];    }    return false;}bool dfs(int now){    if(now==n+1)    {        if(++tot==k) return true;        return false;    }    for(int i=0;i<g[now].size();i++)    {        int flo=g[now][i];        if(!use[flo]&&isok(now,flo))        {            use[flo]=1;            ans[now]=flo;            if(dfs(now+1)) return true;;            use[flo]=0;        }    }    return false;}int a[205][205];int main(){    int cas;    scanf("%d",&cas);    int x;    int ca=1;    while(cas--)    {        for(int i=0;i<=n;i++) g[i].clear();        memset(vis,0,sizeof(vis));        memset(a,0,sizeof(a));        memset(maps,0,sizeof(maps));        scanf("%d%d%d",&n,&m,&k);        for(int i=1;i<=m;i++)        {            for(int j=1;j<=n;j++)            {                scanf("%d",&x);                a[j][x]=1;            }        }        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                if(!a[i][j]) g[i].push_back(j);            }        }        int Ans=0;        for(int i=1;i<=n;i++)        {            memset(vis,0,sizeof(vis));            Ans+=find(i,-1);        }        if(Ans!=n)        {            printf("Case #%d: -1\n",ca++);            continue;        }        tot=0;        memset(use,0,sizeof(use));        if(dfs(1))        {            printf("Case #%d:",ca++);            for(int i=1;i<=n;i++)            {                printf(" %d",ans[i]);            }        }        else printf("Case #%d: -1",ca++);        puts("");    }    return 0;}


读书人网 >编程

热点推荐