[ 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;
}



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