http://poj.org/problem?id=1486
题意:给n个矩形的4个边界的坐标(左上和右下),分别是:xmin、xmax、ymin、ymax。又给出四个数字的坐标。每个数字只能属于一个矩形。求出每个数字的从属关系。
题解:二分图最大匹配问题:数字和矩形的匹配。要求出每一条必须边。先求出最大匹配ans,然后删除每一条边,再进行匹配,看最大匹配是否等于ans:如果相等,则这条边不是必须边;如果
小于ans,则这条边是必须边。
注意点:删除边之后要恢复这条边;输出格式……
1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <cmath>
6 #include <string>
7 #include <vector>
8 #include <list>
9 #include <map>
10 #include <queue>
11 #include <stack>
12 #include <bitset>
13 #include <algorithm>
14 #include <numeric>
15 #include <functional>
16 #include <set>
17 #include <fstream>
18
19 using namespace std;
20
21 const int maxn=110;
22 int V;
23 int G[maxn][maxn];
24 int match[maxn];
25 int used[maxn];
26 int n;
27 struct cos{
28 int xmin,xmax,ymin,ymax;
29 }s[maxn];
30 struct numb{
31 int x,y;
32 }num[maxn];
33
34 bool dfs(int v)
35 {
36 for (int i=0; i<n; i++) {
37 if (!used[i]&&G[v][i]) {
38 used[i]=1;
39 if (match[i]==-1||dfs(match[i])) {
40 match[i]=v;
41 return true;
42 }
43 }
44 }
45 return false;
46 }
47
48 int bipartite_matching()
49 {
50 int res=0;
51 memset(match, -1, sizeof(match));
52 for (int v=0; v<V; v++) {
53 // if (match[v]<0) {
54 memset(used, 0, sizeof(used));
55 if (dfs(v)) {
56 res++;
57 }
58 //}
59 }
60 return res;
61 }
62 int main()
63 {
64 //freopen("/Users/apple/Desktop/POJ 1486/POJ 1486/in", "r", stdin);
65 // freopen("/Users/apple/Desktop/POJ 1486/POJ 1486/out", "w", stdout);
66 int mycase=0;
67 while ((scanf("%d",&n))!=EOF&&n!=0) {
68 V=n;
69 mycase++;
70 memset(G, 0, sizeof(G));
71 for (int i=0; i<n; i++) {
72 scanf("%d%d%d%d",&s[i].xmin,&s[i].xmax,&s[i].ymin,&s[i].ymax);
73 }
74 for (int i=0; i<n; i++) {
75 scanf("%d%d",&num[i].x,&num[i].y);
76 }
77 for (int i=0; i<n; i++) {
78 for (int j=0; j<n; j++) {
79 if ((num[j].x>=s[i].xmin)&&(num[j].x<=s[i].xmax)&&(num[j].y>=s[i].ymin)&&(num[j].y<=s[i].ymax)) {
80 G[i][j]=1;
81 }
82 }
83 }
84 printf("Heap %d\n",mycase);
85 int ans=bipartite_matching();
86 bool flag=false;
87 for (int i=0; i<n; i++) {
88 for (int j=0; j<n; j++) {
89 if (G[i][j]==0) {
90 continue;
91 }
92 G[i][j]=0;
93 if (bipartite_matching()<ans) {
94 flag=true;
95 printf("(%c,%d) ",‘A‘+i,j+1);
96 }
97 G[i][j]=1;
98 }
99 }
100 if (flag==0) {
101 printf("none\n\n");
102 }
103 else printf("\n\n");
104 }
105 return 0;
106 }
时间: 2024-10-25 17:00:19