poj 1486 Sorting Slides(二分图匹配必要边)

题目描述

poj 1486 Sorting Slides(二分图匹配必要边)_第1张图片

分析

先求一个最大匹配,然后对与每一条匹配边,删除以后搜一下增广路,如果存在增光路则这不是必要边,如果不存在,说明这就是一条必要边.

code

#include 
#include 
#include 
#include 

#define fi first
#define se second
using namespace std;

int G[60][60];

typedef long long LL;
typedef pair<int,int> PII;


struct slide{
  int xmin,xmax,ymin,ymax;
   bool contain(PII point){
    return point.fi>=xmin&&point.fi<=xmax&&point.se>=ymin&&point.se<=ymax;
  }
};
int n;
slide s[30];
PII point[30];
int vis[30<<1];
int match[30<<1];
int dfs(int u){

  for(int i=0 ; iif(G[u][i] && !vis[i]){
        vis[i] = 1;
      if(match[i] == -1 || dfs(match[i])){
        match[i] = u;
        return true;
      }
    }
  }
  return false;
}

int hungarian(){
  int ans = 0;
  memset(match,-1,sizeof(match));
  for( int i=0 ; imemset(vis,0,sizeof(vis));
      ans+=dfs(i);
  }
  return ans;
}
int res[30];
int main(int argc, char const *argv[]) {
  int t = 0;
  while (scanf("%d",&n ) && n) {
    memset(G,0,sizeof(G));
    memset(vis,0,sizeof(vis));
    memset(res,-1,sizeof(res));
    if(t)printf("\n");
    printf("Heap %d\n", ++t);
    for(int i=0 ; iscanf("%d%d%d%d",&s[i].xmin,&s[i].xmax,&s[i].ymin,&s[i].ymax );
    for(int i=0;iscanf("%d%d",&point[i].fi,&point[i].se );
    for(int i=0 ; ifor(int j=0 ; jif(s[i].contain(point[j]))G[i][j] = 1;
    }
    int ans = hungarian();
    bool flag = false;
    for(int i=0 ; iint v = match[i];
      match[i] = -1;
      G[v][i] = 0;
      memset(vis,0,sizeof(vis));
      if(!dfs(v)){//唯一
        res[v] = i;
        flag = true;
        match[i] = v;
      }
      G[v][i] = 1;
    }
    if(!flag)printf("none\n" );
    else {
        int first = 0;
        for(int i=0 ; iif(res[i]!=-1){
            if(first)printf(" ");
            printf("(%c,%d)",'A'+i,res[i]+1);
            first = 1;
        }
        printf("\n");
    }
  }
  return 0;
}

你可能感兴趣的:(算法刷题)