poj1486(二分图删边匹配)
来源:互联网 发布:软件管家官网 编辑:程序博客网 时间:2024/05/21 19:23
题意:给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-8const 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;}
0 0
- poj1486(二分图删边匹配)
- poj1486(二分图匹配)
- poj1486 (二分图匹配)
- POJ1486 Sorting Slides【二分匹配】
- poj1486 二分匹配的唯一边
- POJ1486 Sorting Slides 二分图最大匹配 必要匹配
- poj1486 sorting slides (二分图最大匹配的唯一性)
- poj1486 Sorting Slides 二分图匹配的必须边
- POJ1486 Sorting Slides (二分图求最大匹配)
- 二分图必须边--poj1486
- POJ1486 Sorting Slides 二分图
- Sorting Slides(poj1486,绝对匹配边)
- 二分匹配(入门)
- hdu2444(二分匹配)
- 二分匹配(模板)
- Chessboard(二分匹配)
- hdu1507(二分匹配)
- 二分匹配模板()
- 关于使用Visual C++ 编写API(Application Programming Interface)函数时编译那点事
- 正则表达式 (入门)
- 简单了解java正则表达式的用法
- 驱动对象结构DRIVER_OBJECT
- Windows/Linux上weka的配置
- poj1486(二分图删边匹配)
- Objective-C内存管理教程和原理剖析(一)
- android获取所有短信
- Android 4.0.4-在build.prop中添加属性
- 利用C语言创建和使用DLL文件
- HTML语言高级
- 在ASP.NET使用javascript的一点小技巧
- 全文本检索的应用
- Objective-C内存管理教程和原理剖析(二)