UVA663 Sorting Slides(烦人的幻灯片)
UVA663 Sorting Slides(烦人的幻灯片)
UVA663 Sorting Slides(烦人的幻灯片)
第一次做到这么玄学的题,在《信息学奥赛一本通》拓扑排序一章找到这个习题(却发现标程都是错的),结果用二分图匹配做了出来
蒟蒻感觉思路不太好想,难度大概在蓝题~紫题,至于为什么是黑题。。
那是因为UVa输出换行空格万年老坑
#include<cstdio>
#include<cstring>
using namespace std;
#define N 27
int vis[N],match[N],ans[N],x1[N],x2[N],y1[N],y2[N],n,T;
bool g[N][N],flag;
inline bool dfs(int x) {
for (register int i=1; i<=n; i++)
if (!vis[i] && g[x][i]) {
vis[i]=1;
if (!ans[i] || dfs(ans[i])) {
ans[i]=x;//第 i 个幻灯片对应数字为 x
return true;
}
}
return false;
}
inline int find() {//求二分图最大匹配
int sum=0;
memset(ans,0,sizeof ans);
for (register int x=1; x<=n; x++){
memset(vis,0,sizeof vis);
if (dfs(x)) sum++;// 总匹配数
}
return sum;
}
int main() {
while(~scanf("%d",&n) && n) {
printf("Heap %d\n",++T);
memset(g,0,sizeof g);
for (int i=1; i<=n; i++)
scanf("%d%d%d%d",&x1[i],&x2[i],&y1[i],&y2[i]);
for (int i=1,x,y; i<=n; i++) {
scanf("%d%d",&x,&y);
for (int j=1; j<=n; j++)
if (x>=x1[j] && x<=x2[j] && y>=y1[j] && y<=y2[j])
g[i][j]=1;//如果数字在幻灯片范围之内的话则连边,有机会匹配
}
int tot=find(),flag=0;
自此已求出当前的匹配,但程序还未结束,如果在此输出答案:
for (int i=1;i<=n;i++) printf("(%c,%d)",i-1+'A',ans[i]);
按照样例数据,你会发现第一组数据已有正确答案,而第二组数据不是none,而输出了匹配情况
这是因为题目还有一个要求:
若出现多种对应的情况,我们称这种对应是无法实现的。
第二组数据中A和B都可以匹配1和2中任意一个,所以对应不唯一
//接下来我们要去除这种情况
for (int j=1; j<=n; j++)
for (int i=1;i<=n; i++)
if (g[i][j]) {
g[i][j]=0;//考虑依次删去每条边,如果有唯一对应,那么至少有一边删去后使匹配数减少
if (find()!=tot) {
if (flag) printf(" ");
else flag=1;
printf("(%c,%d)",j-1+'A',i);//如果幻灯片 j 与 数字 i 是唯一搭配,直接输出
}
g[i][j]=1;
}
if (!flag) printf("none");//如果删去任意一边匹配数都不变,则对应不唯一
puts("\n");//相当于printf("\n\n");
}
return 0;
}
萌新的第一篇黑题题解,第一次给没有题解的题写题解,第二道黑题QWQ