HDU 3729 I'm Telling the Truth

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3729


题意:一共有N个点,每一个点分别对应一个区间里任意一个数,要求出所有可以匹配的点


思路:刚开始以为是区间贪心,按照其左区间进行了排序进行贪心,wa了几次,但是并没有发现哪里错了……后来看了别人的题解,发现是利用二分图照增广路来进行匹配,有多个答案要输出字典序最大的序列,匈牙利算法的时间复杂度是O(V*E)。


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;

int n,List[100030],vis[100030],save[100030];
vector <int> G[65];
int Find(int u)
{
    for (int i=0;i<G[u].size();i++)
    {
        int tem=G[u][i];
        if (vis[tem]==0)
        {
            vis[tem]=1;
            if (List[tem]==-1 || Find(List[tem]))
            {
                List[tem]=u;
                return 1;
            }
        }
    }
    return 0;
}

int solve()
{
    int sum=0;
    for (int i=n-1;i>=0;i--)
    {
        memset(vis,0,sizeof(vis));
        if (Find(i)) sum++;

    }
    return sum;
}

int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        for (int i=0;i<=60;i++)
            G[i].clear();
        memset(List,-1,sizeof(List));
        scanf("%d",&n);
        int minn=0x3f3f3f3f,maxn=-1;
        for (int i=0;i<n;i++)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            if (minn>l) minn=l;
            if (maxn<r) maxn=r;
            while (l<=r)
            {
                G[i].push_back(r);
                r--;
            }
        }
        int res=solve(),tem=0;
        cout<<res<<endl;
        for (int i=minn;i<=maxn;i++)
        {
            if (List[i]!=-1)
            save[tem++]=List[i]+1;
        }
        sort(save,save+tem);
        for (int i=0;i<tem;i++)
        {
            printf("%d",save[i]);
            if (i!=tem-1) printf(" ");
            else printf("\n");

        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值