[ ZOJ 1197 ] [POJ 1486] Sorting Slides

ZOJ: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1197

POJ: http://poj.org/problem?id=1486


题目大意:

有一些透明的幻灯片乱放成一大堆。每张幻灯片上写有编号,但是透明的幻灯片叠在一起,看不清楚每个数字是写在哪一张上的。

例如题图中,用字母A,B,C,D给幻灯片编号,可以推测出D上写有3,B上写有1,C上写有2,A上写有4。


解题思路:

幻灯用A..Z表示,那么n最大只有26。根据幻灯座标范围和数字座标建立二分图。

对于每张幻灯片,每次删掉和一个数字的连边(如果有),如果仅有某一条边可以使余下边的最大匹配为n-1,则字母和数字配对唯一。

又没有注意到“Output a blank line after each test case.”,又PE了,想拿板砖拍死自己……


源代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 30

bool MaxMatchDFS(bool g[][maxn], int m, int a, int y[], bool u[])
{
    for (int i=0; i<m; i++)
        if (!u[i] && g[a][i])
        {
            int t=y[i];
            u[i]=true; y[i]=a;
            if (t==-1 || MaxMatchDFS(g, m, t, y, u)) return true;
            y[i]=t;
        }
    return false;
}
int MaxMatch(bool g[][maxn], int n, int m) //v1[y[i]] matches v2[i]
{
    int y[maxn];
    memset(y, 255, sizeof(y));
    int c=0;
    for (int i=0; i<n; i++)
    {
        bool u[maxn]={0};
        if (MaxMatchDFS(g, m, i, y, u)) c++;
    }
    return c;
}

bool init(bool g[][maxn], int &n)
{
    int xmin[maxn], xmax[maxn], ymin[maxn], ymax[maxn];
    int x[maxn], y[maxn];
    scanf("%d", &n);
    if (n==0) return false;
    for (int i=0; i<n; i++)
        scanf("%d%d%d%d", &xmin[i], &xmax[i], &ymin[i], &ymax[i]);
    for (int i=0; i<n; i++)
        scanf("%d%d", &x[i], &y[i]);
    memset(g, false, sizeof(*g)*maxn);
    for (int i=0; i<n; i++)
        for (int j=0; j<n; j++)
        {
            if (xmin[i]<x[j] && xmax[i]>x[j]
                && ymin[i]<y[j] && ymax[i]>y[j])
            g[i][j]=1;
        }
    return true;
}

int main()
{
    int cs=0;
    int n, unique, match; 
    bool g[maxn][maxn];
    bool found;
    while (init(g, n))
    {
        found=false;
        printf("Heap %d\n", ++cs);
        for (int i=0; i<n; i++)
        {
            unique=-1;          //0:false 1:true -1:don't know
            match=-1;
            for (int j=0; j<n; j++)
                if (g[i][j])
                {
                    g[i][j]=false;
                    if (MaxMatch(g, n, n)==n-1)
                    {
                        if (unique==-1){unique=1;match=j;}
                        else {unique=0; break;}
                    }
                    g[i][j]=true;
                }
            if (unique==1)
            {
                if (found==false) found=true;
                else printf(" ");
                printf("(%c,%d)", i+'A', match+1);
            }
        }
        if (found==false) printf("none\n\n");
        else printf("\n\n");
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章