POJ 1486 Sorting Slides(二分图最大匹配:关键边)
2017-08-22 11:52
411 查看
POJ 1486 Sorting Slides(二分图最大匹配:关键边)
http://poj.org/problem?id=1486
题意:
一些幻灯片,有一些数字在幻灯片里面,看能不能使得一个数字只能对应一张幻灯片.第一行代表有几张幻灯片.
给出这几张幻灯片的坐标,接着n行代表1-n个数字对应的坐标,然后要求你打印一个确定的使一个数字对应一张幻灯片.
如果不能对应输出none.
存在某些幻灯片只能由某个数字代表的话就按字典序打印出这些幻灯片和对应的数字.
分析:
其实就是二分图最大匹配问题.左边点集用幻灯片编号表示,右边点集用数字表示. 如果某个幻灯片i包含了数字j,那么从左边i到右边j就存在一条边.
首先我们求出这个图的最大匹配数x, 根据题意这x值一定是等于n(幻灯片数的). 然后我们记录目前求到的最大匹配的各个边.
我们每次判断最大匹配边集的某条边是否是必需边. 我们只要先删除这条边,如果之后求最大匹配数依然==n,那么这条边不是必需边.如果之后求最大匹配数依然<n,那么这条边是必需边.(做好标记)
最终我们只需要输出所有的必须边即可.
注意:最后输出所有可以确定的边即可,全部都输出none
AC代码:
http://poj.org/problem?id=1486
题意:
一些幻灯片,有一些数字在幻灯片里面,看能不能使得一个数字只能对应一张幻灯片.第一行代表有几张幻灯片.
给出这几张幻灯片的坐标,接着n行代表1-n个数字对应的坐标,然后要求你打印一个确定的使一个数字对应一张幻灯片.
如果不能对应输出none.
存在某些幻灯片只能由某个数字代表的话就按字典序打印出这些幻灯片和对应的数字.
分析:
其实就是二分图最大匹配问题.左边点集用幻灯片编号表示,右边点集用数字表示. 如果某个幻灯片i包含了数字j,那么从左边i到右边j就存在一条边.
首先我们求出这个图的最大匹配数x, 根据题意这x值一定是等于n(幻灯片数的). 然后我们记录目前求到的最大匹配的各个边.
我们每次判断最大匹配边集的某条边是否是必需边. 我们只要先删除这条边,如果之后求最大匹配数依然==n,那么这条边不是必需边.如果之后求最大匹配数依然<n,那么这条边是必需边.(做好标记)
最终我们只需要输出所有的必须边即可.
注意:最后输出所有可以确定的边即可,全部都输出none
AC代码:
#include <cstdio> #include <algorithm> #include <iostream> #include <cstring> #include<stack> #include<vector> using namespace std; const int maxn=50; struct Max_Match { int n,m; int g[maxn][maxn]; bool vis[maxn]; int left[maxn]; void init(int n,int m) { this->n=n; this->m=m; memset(g,0,sizeof g); memset(left,-1,sizeof left); } bool match(int u) { for(int i=1;i<=n;i++) { if(g[u][i]&&!vis[i]) { vis[i]=true; if(left[i]==-1||match(left[i])) { left[i]=u; return true; } } } return false; } int solve() { int ans=0; for(int i=1;i<=n;i++) { memset(vis,false,sizeof vis); if(match(i))ans++; } return ans; } }MM; struct node { int x 4000 1,x2,y1,y2; }s[maxn*2]; bool check(int i,int j) { if(s[i].x1<=s[j].x1&&s[j].x1<=s[i].x2) { if(s[i].y1<=s[j].y1&&s[j].y1<=s[i].y2) { return true; } } return false; } struct edge { int x,y; int ok; }edges[maxn*2]; int main() { int n; int cas=1; while(~scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) { scanf("%d%d%d%d",&s[i].x1,&s[i].x2,&s[i].y1,&s[i].y2); } for(int i=1;i<=n;i++) { scanf("%d%d",&s[i+n].x1,&s[i+n].y1); } MM.init(n,n); for(int i=n+1;i<=2*n;i++) { for(int j=1;j<=n;j++) { if(check(j,i)) { //cout<<"+++"<<endl; MM.g[i-n][j]=true; } } } printf("Heap %d\n",cas++); MM.solve(); /*for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(MM.g[i][j]) { printf("%d %d\n",i,j); } }*/ for(int i=1;i<=n;i++) { edges[i].x=MM.left[i]; edges[i].y=i; edges[i].ok=true; } int ok=1; int num=n; for(int i=1;i<=n;i++) { MM.g[edges[i].x][edges[i].y]=false; memset(MM.left,-1,sizeof MM.left); //cout<<MM.solve()<<endl; if(MM.solve()==n) { edges[i].ok=false; num--; } MM.g[edges[i].x][edges[i].y]=true; } if(num!=0) { int flag=0; for(int i=1;i<=n;i++) { if(!flag&&edges[i].ok) { printf("(%c,%d)",'A'+i-1,edges[i].x); flag=1; } else if(flag&&edges[i].ok) printf(" (%c,%d)",'A'+i-1,edges[i].x); } printf("\n"); } else { printf("none\n"); } printf("\n"); } }
相关文章推荐
- POJ 1486 Sorting Slides(二分图最大匹配:关键边)
- POJ - 1486 Sorting Slides 二分图最大匹配(求关键边)
- POJ 1486 Sorting Slides(二分图最大匹配:关键边)
- POJ 1486 Sorting Slides (二分图关键匹配边)
- poj1486 sorting slides (二分图最大匹配的唯一性)
- POJ1486 Sorting Slides (二分图求最大匹配)
- POJ 1486 Sorting Slides (二分图关键匹配边)
- poj 1486 二分图最大匹配必须边
- POJ 1486 二分图最大匹配 必要匹配
- POJ 1486 Sorting Slides 最大二分匹配 匈牙利算法
- POJ 1486 Sorting Slides 二分图关键边 匈牙利算法
- POJ 1486 二分图的最大匹配(强化)
- POJ1486 Sorting Slides 二分图最大匹配 必要匹配
- POJ-1274 The Perfect Stall(二分图最大匹配)
- POJ 1469 二分图最大匹配
- POJ 3020 Antenna Placement(二分图的最大匹配)
- POJ3020——Antenna Placement(二分图的最大匹配)
- poj 1087 A Plug for UNIX 二分图最大匹配
- 二分图最大匹配题目汇总 POJ 1274、2239、3020、3715
- 【二分图+最大匹配】北大 poj 1274 The Perfect Stall