POJ1486 Sorting Slides【二分匹配】

来源:互联网 发布:多处理器编程的艺术 编辑:程序博客网 时间:2024/05/22 07:59

题意:给出幻灯片的区域和页码的坐标,求唯一确定的匹配


思路:利用匈牙利算法求最大匹配,把这些边记录下来,然后逐一检查这些边,把边删去,再次匹配,若最大匹配数没变,说明这条边,不是唯一的,再把边恢复。


#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<stdlib.h>#include<math.h>#include<vector>#include<list>#include<map>#include<stack>#include<queue>#include<algorithm>#include<numeric>#include<functional>using namespace std;typedef long long ll;const int maxn = 505;int dis[maxn][maxn];int girl[maxn],vis[maxn];int ans[maxn],n;struct data{int x1,x2,y1,y2;}node[maxn];struct edge{int from,to,ok;}ed[maxn*maxn];int cnt;int px[maxn],py[maxn];void init(){memset(girl,-1,sizeof girl);memset(dis,0,sizeof dis);}int fid(int x) // 为匹配x {for(int j = 1; j <= n; j++){if(!vis[j] && dis[x][j]){vis[j] = 1;if(girl[j] == -1 || fid(girl[j]) ){girl[j] = x;return 1;}}}return 0;}void add(int x,int y){dis[x][y] = 1;}int check(int x,int y){if(px[x] >= node[y].x1 && px[x] <= node[y].x2 && py[x] >= node[y].y1 && py[x] <= node[y].y2)return 1;elsereturn 0;}int main(void){int i,j,k,kase = 1;while(scanf("%d",&n)!=EOF && n){init();for(i = 1; i <= n; i++){scanf("%d%d%d%d",&node[i].x1,&node[i].x2,&node[i].y1,&node[i].y2);}cnt = 0;for(i = 1; i <= n; i++){scanf("%d%d",&px[i],&py[i]);for(j = 1; j <= n; j++){if(check(i,j))add(j,i);}}memset(girl,-1,sizeof girl);int sum = 0;for(j = 1; j <= n; j++){memset(vis,0,sizeof vis);if(fid(j))sum++;}for(i = 1; i <= n; i++){ed[girl[i]].from = girl[i];ed[girl[i]].to = i;ed[i].ok = 1;}int bian = sum;for(i = 1; i <= n; i++){dis[ed[i].from][ed[i].to] = 0;int num = 0;memset(girl,-1,sizeof girl);for(j = 1; j <= n; j++){memset(vis,0,sizeof vis);if(fid(j))num++;}if(num == n) //must{ed[i].ok = 0;bian--;}dis[ed[i].from][ed[i].to] = 1;}printf("Heap %d\n",kase++);if(bian != 0){for(i = 1; i <= n; i++) if(ed[i].ok)printf("(%c,%d) ",'A'+i-1,ed[i].to);putchar('\n');}elseprintf("none\n");putchar('\n');}return 0;}