hdu_1507 Uncle Tom's Inherited Land* 二分图匹配

来源:互联网 发布:邮箱搜索软件 编辑:程序博客网 时间:2024/05/22 05:28
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;#define N 102struct node{    int x,y;}s[N*N];bool edge[N][N];vector<int>g[N*N];int linker[N*N];bool vis[N*N];bool dfs(int u){    for(int i=0;i<g[u].size();i++){        int v=g[u][i];        if(!vis[v]&&((s[v].x+s[v].y)%2==0)){            vis[v]=1;            if(linker[v]==-1||dfs(linker[v])){                linker[v]=u;                return true;            }        }    }    return false;}int hungary(int ans){    memset(linker,-1,sizeof(linker));    int cnt=0;    for(int i=0;i<ans;i++){        memset(vis,0,sizeof(vis));        if((s[i].x+s[i].y)%2==1)        if(dfs(i)) cnt++;    }    return cnt;}int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF){        if(!n&&!m) break;        int num;        memset(edge,0,sizeof(edge));        int r,c;        scanf("%d",&num);        while(num--){            scanf("%d%d",&r,&c);            edge[r][c]=1;        }        for(int i=1;i<=n*m;i++)            g[i].clear();        int ans=0;        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                if(edge[i][j]) continue;                s[ans].x=i;                s[ans].y=j;                ans++;            }        }                for(int i=0;i<ans;i++){            for(int j=0;j<ans;j++){                if((s[i].x==s[j].x)&&(s[i].y+1==s[j].y)||(s[i].x==s[j].x)&&(s[i].y-1==s[j].y)||(s[i].y==s[j].y)&&(s[i].x+1==s[j].x)||(s[i].y==s[j].y)&&(s[i].x-1==s[j].x)){                    if((s[i].x+s[i].y)%2==1)                    g[i].push_back(j);                }            }        }        /*for(int i=0;i<ans;i++){            for(int j=0;j<g[i].size();j++){                printf("%d---%d ",i,g[i][j]);            }            printf("************\n");        }*/        printf("%d\n",hungary(ans));        for(int i=0;i<ans;i++){            if(linker[i]!=-1){            printf("(%d,%d)--(%d,%d)\n",s[i].x,s[i].y,s[linker[i]].x,s[linker[i]].y);            }        }        printf("\n");    }    return 0;}

哎!就是二分图,当时为什么一定要分奇偶匹配???为什么不能在输出的时候标记进行解决呢?

下面是有疑问的代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;#define N 110bool edge[N][N];struct node{int x,y;}s[100*N];vector<int> g[100*N];int linker[100*N];bool vis[100*N];bool flag[N][N];bool dfs(int u){for(int i=0;i<g[u].size();i++){int v=g[u][i];if(!vis[v]){vis[v]=1;if(linker[v]==-1||dfs(linker[v])){linker[v]=u;return true;}}}return false;}int hungary(int ans){memset(linker,-1,sizeof(linker));int cnt=0;for(int i=0;i<ans;i++){memset(vis,0,sizeof(vis));if(dfs(i)) cnt++;}return cnt;}void getmatch(int ans){memset(flag,0,sizeof(flag));for(int i=0;i<ans;i++){if(linker[i]==-1) continue;int u=linker[i];if(flag[s[u].x][s[u].y]||flag[s[i].x][s[i].y]) continue;printf("(%d,%d)--(%d,%d)\n",s[i].x,s[i].y,s[u].x,s[u].y);flag[s[i].x][s[i].y]=1;flag[s[u].x][s[u].y]=1;}puts("");}int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){if(!n&&!m) break;int num;int r,c;scanf("%d",&num);for(int i=0;i<n*m;i++)g[i].clear();memset(edge,0,sizeof(edge));while(num--){scanf("%d%d",&r,&c);edge[r][c]=1;}int ans=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(edge[i][j]) continue;s[ans].x=i;s[ans].y=j;ans++;}}for(int i=0;i<ans;i++){for(int j=i+1;j<ans;j++){if((s[i].x==s[j].x&&s[i].y==s[j].y+1)||(s[i].x==s[j].x&&s[i].y==s[j].y-1)||(s[i].x-1==s[j].x&&s[i].y==s[j].y)||(s[i].x+1==s[j].x&&s[i].y==s[j].y)){g[i].push_back(j);g[j].push_back(i);}}}printf("%d\n",hungary(ans)/2);getmatch(ans);}return 0;}

希望有人看到指点下。。。。。!