二分图 crf的军训

这里写图片描述
这里写图片描述
这里写图片描述

这道题的数据(至少我们oj的)有问题!按照我下面的做法能够过数据,但并不是正解。(我在代码后面说一下这数据错哪里了。。)
二分图即可,也没必要拆点,其实只是把点视为两排,在左边一排向右边能连边的点连边(说白了就是左边点能放右边点后面),之后把右边点的link设为左边点。就这样。。考试时以为是dp,最后交了深搜。。。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n, ans=0, idc=0;
int a[305][305],vis[305],l[305];
struct Book{int x, y;}book[305];
//inline bool cmp(Book x,Book y){return x.x==y.x?x.y>y.y:x.x>y.y;}
inline int find(int x)
{
    for(int i=1;i<=n;i++)
    if(!vis[i]&&a[x][i])
    {
        vis[i]=1;
        if(!l[i]||find(l[i]))
        {
            l[i]=x;
            return 1;
        }
    }
    return 0;
}
int main(){
  //  freopen ("militarytraining.in", "r", stdin);
 //   freopen ("militarytraining.out", "w", stdout);
    scanf("%d", &n);
    for(int i=1; i<=n; i++)scanf("%d%d", &book[i].x, &book[i].y);
    //sort(book+1, book+n+1,cmp);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(i!=j&&book[i].y>=book[j].y&&book[i].x>=book[j].x)
                a[j][i]=1;
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        ans+=find(i);
    }
    printf("%d
", n-ans);
}

二分图只能处理无DAG的情况,若存在DAG,对于这道题也就是完全相等的书之间可以互相放,但这种环会形成把1放在2后,并且2在1后面的灵异现象。说白了就是不对。所以要么拆成2×n个点,或者缩掉所有相等的点。呵呵。。。。

原文地址:https://www.cnblogs.com/QTY2001/p/7632661.html