uva 3126 出租车 (最小路径覆盖)

给出m个客人的行程。问最少需要的出租车数量。


模型:最小路径覆盖:用最少的路径覆盖所有点(客人)


建图:如果接完上一个客人u能够来得及接下一个客人v,则u到v连一条有向边,由此得到一个DAG图。然后将每个客人拆为两个点X、Y,如果X1->X2有边,则X1->Y2连一条边,以此得到一个二分图,然后求最大匹配。

性质:最小路径覆盖数=原图顶点数-二分图最大匹配。(二分图中每有一个匹配,原图中有一条顶点不相交的边,需要的路径数减少1)。


关于最小路径覆盖


#include<bits/stdc++.h>
using namespace std;
struct Point{
    int x,y;
};
struct P{
    int time;
    Point s,e;
}a[505];

bool M[505][505],T[505];
int Left[505],m;

int match(int u){
    for(int i=u+1;i<m;++i){
        if(M[u][i]&&!T[i]){
            T[i]=1;
            if(!Left[i]||match(Left[i])){
                Left[i]=u;
                return 1;
            }
        }
    }
    return 0;
}
int Dis(Point x,Point y) {return abs(x.x-y.x)+abs(x.y-y.y);}
int main()
{
    int t,i,j,Ti,Mi;
    Point s,e;
    cin>>t;
    while(t--){
        scanf("%d",&m);
        for(i=0;i<m;++i){
            scanf("%02d:%02d %d %d %d %d",&Ti,&Mi,&s.x,&s.y,&e.x,&e.y);
            a[i].time=Ti*60+Mi;
            a[i].s=s;
            a[i].e=e;
        }
        memset(M,0,sizeof(M));
        for(i=0;i<m;++i)
            for(j=i+1;j<m;++j)
                if(a[i].time+Dis(a[i].s,a[i].e)+Dis(a[i].e,a[j].s)+1<=a[j].time) M[i][j]=1;
        int ans=0;
        memset(Left,0,sizeof(Left));
        for(i=0;i<m;++i){
            for(j=0;j<m;++j) T[j]=0;
            ans+=match(i);
        }
        printf("%d\n",m-ans);
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值