hdu 3360

来源:互联网 发布:如何用c语言开发软件 编辑:程序博客网 时间:2024/06/06 23:20

奇偶染色,将有冲突要求的位置连一条边,求最小点覆盖~~

有一个主意点必须要双向检查~~

#include <iostream>#include <cstring>#include <cstdio>using namespace std;int map[55][55];int xid[5555];int yid[5555];struct node{    int u,v;};node edge[755555];int first[75555],next[755555];int vis[55555];int cc,n,m,x_id,y_id;int linker[55555];int xx[12]={-1,-2,-2,-1,1,2,2,1,-1,0,1,0};int yy[12]={-2,-1,1,2,2,1,-1,-2,0,1,0,-1};inline void add_edge(int u,int v){    edge[cc].u=u;    edge[cc].v=v;    next[cc]=first[u];    first[u]=cc;    cc++;}bool dfs(int u){    int i;    for(i=first[u];i!=-1;i=next[i])    {        int v=edge[i].v;        if(!vis[v])        {            vis[v]=1;            if(linker[v]==-1||dfs(linker[v]))            {                linker[v]=u;                return true;            }        }    }    return false;}int match(int n){    int i;    int res=0;    memset(linker,-1,sizeof(linker));    for(i=1;i<=n;i++)    {        memset(vis,0,sizeof(vis));        if(dfs(i))            res++;    }    return res;}void bfind(int mm){    int x=mm/m;    int y=mm%m;    int i;    if(map[x][y]==-1)        return ;    for(i=0;i<12;i++)    {        if((1<<i)&map[x][y])        {                        int nx=x+xx[i];            int ny=y+yy[i];            if(nx>=n||nx<0||ny>=m||ny<0)                continue;            if(map[nx][ny]==-1)                continue;            if((x+y)%2==0)                add_edge(xid[mm],x_id-1+yid[nx*m+ny]);            else                add_edge(xid[nx*m+ny],x_id-1+yid[mm]);        }    }}int main(){    int cas=0;    while(scanf("%d%d",&n,&m)!=EOF)    {        if(n==0&&m==0)            break;        cas++;        int i,j;        x_id=1;        y_id=1;        memset(xid,0,sizeof(xid));        memset(yid,0,sizeof(yid));        memset(first,-1,sizeof(first));        memset(next,-1,sizeof(next));        cc=0;        for(i=0;i<n;i++)        {            for(j=0;j<m;j++)            {                scanf("%d",&map[i][j]);                int x=i*m+j;                if((i+j)%2==0)                    xid[x]=x_id++;                else                    yid[x]=y_id++;            }        }        for(i=0;i<n;i++)        {            for(j=0;j<m;j++)            {                bfind(i*m+j);            }        }        int res=match(x_id-1);        printf("%d. %d\n",cas,res);    }    return 0;}


原创粉丝点击