poj 1486 二分图最大匹配必须边

来源:互联网 发布:重装linux系统有pe 编辑:程序博客网 时间:2024/06/05 07:38

题意:就是求点和矩形的最大匹配。如果有这种唯一的对应关系则输出,没有的话输出none

思路:点和矩阵建立连接,然后求最大匹配。同时注意删边的技巧。

#include<iostream>#include<cmath>using namespace std;struct point{  int x,y;}P[100];struct rec{  int minx;  int miny;  int maxx;  int maxy;}R[100];bool g[100][100];bool vis[100];int link[100];int N;bool check(int i,int j){  int xx=P[i].x;  int yy=P[i].y;  if(xx>R[j].minx&&xx<R[j].maxx&&yy>R[j].miny&&yy<R[j].maxy)  return true;  return false;}bool dfs(int u){  for(int i=1;i<=N;i++)  {    if(!vis[i]&&g[u][i])    {      vis[i]=1;      if(link[i]==-1||dfs(link[i]))      {        link[i]=u;        return true;      }    }  }  return false;}int maxmatch(){  int num=0;  memset(link,-1,sizeof(link));  for(int i=1;i<=N;i++)  {    memset(vis,0,sizeof(vis));    if(dfs(i))  num++;  }  return num;}int main(){  int h=1;  while(scanf("%d",&N)!=EOF&&N)  {    for(int i=1;i<=N;i++)    scanf("%d%d%d%d",&R[i].minx,&R[i].maxx,&R[i].miny,&R[i].maxy);    for(int i=1;i<=N;i++)    scanf("%d%d",&P[i].x,&P[i].y);    memset(g,0,sizeof(g));    for(int i=1;i<=N;i++)      for(int j=1;j<=N;j++)       {         if(check(i,j))         {           g[i][j]=1;           //printf("(%d,%d)\n",i,j);         }       }       maxmatch();//先求出最大匹配       //枚举边 i代表y图的节点 也就是矩形的标号       bool flag=false;       bool end=false;       for(int i=1;i<=N;i++)       {         if(link[i]==-1)  continue;//不一定都是完美匹配         int temp=link[i];         link[i]=-1;//删边         g[temp][i]=0;         memset(vis,0,sizeof(vis));         if(!dfs(temp))//从删掉这个边的x图节点temp开始找,看是否存在增广路,如果不存在则是必须边。          {           if(!end)           printf("Heap %d\n",h++);           flag=true;           if(!end)           printf("(%c,%d)",'A'+i-1,temp);           else           printf(" (%c,%d)",'A'+i-1,temp);           end=true;           link[i]=temp;//如果是必须边的话要把link还原          }         //link[i]=temp;           g[temp][i]=1;//不是必须边的话,link已经改变不需要还原,只要把图g还原就可以        }       if(!flag)       {         printf("Heap %d\n",h++);         printf("none\n\n");       }       else       printf("\n\n");  }  //system("pause");}