首页 > 代码库 > poj1486(二分图删边匹配)
poj1486(二分图删边匹配)
题意:给n(n<=26)张幻灯片,每张上面都有一个数字。给出所有幻灯片的位置和数字的位置,问哪些幻灯片上的数字可以确定。
解法:首先,如果给的合法的话,匈牙利算出来的一定是完全匹配的(也就是说,第一遍二分匹配算出来的一定是完全匹配)。然后再尝试删掉每一条完全匹配中的边,如果删掉后不能完全匹配,则说明这条边是必须的,所以就确定了这个匹配并输出。如果算出的完全匹配中没有一个匹配是必须的,就输出none好了。
代码:
/****************************************************** * author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> //freopen ("in.txt" , "r" , stdin); using namespace std; #define eps 1e-8 const double pi=acos(-1.0); typedef long long LL; const int Max=10100; const int INF=1000000007; int n; struct rec { int minx,miny,maxx,maxy; } recs[30]; bool num[30][30]; bool used[30]; int match[30]; int match2[30]; struct point { int x,y; } points[30]; bool OK(const rec& re,const point& p) { return (p.x>=re.minx&&p.x<=re.maxx&&p.y>=re.miny&&p.y<=re.maxy); } bool dfs(int k) { for(int i=0;i<n;i++) { if(used[i]||!num[i][k]) continue; used[i]=1; if(match[i]==-1||dfs(match[i])) { match[i]=k; return 1; } } return 0; } bool dfs2(int k) { for(int i=0;i<n;i++) { if(used[i]||!num[i][k]) continue; used[i]=1; if(match2[i]==-1||dfs(match2[i])) { match2[i]=k; return 1; } } return 0; } bool make() { int tool=0; memset(match,-1,sizeof match); for(int i=0;i<n;i++) { memset(used,0,sizeof used); if(dfs(i)) tool++; else break; } return tool==n; } void solve() { bool flag=1; for(int i=0;i<n;i++) { num[i][match2[i]]=0; if(!make()) { if(!flag) printf(" "); printf("(%c,%d)",‘A‘+i,match2[i]+1); flag=0; } else continue; num[i][match2[i]]=1; } if(flag) printf("none\n"); else printf("\n"); } int main() { int kk=1; while(scanf("%d",&n)==1) { memset(num,0,sizeof num); if(n==0) break; for(int i=0; i<n; i++) scanf("%d%d%d%d",&recs[i].minx,&recs[i].maxx,&recs[i].miny,&recs[i].maxy); for(int i=0; i<n; i++) scanf("%d%d",&points[i].x,&points[i].y); for(int i=0; i<n; i++) for(int j=0; j<n; j++) num[i][j]=OK(recs[i],points[j]); memset(match,-1,sizeof match); int tool=0; printf("Heap %d\n",kk++); for(int i=0;i<n;i++) { memset(used,0,sizeof used); if(dfs(i)) tool++; } for(int i=0;i<n;i++) match2[i]=match[i]; solve(); puts(""); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。