zoukankan      html  css  js  c++  java
  • POJ2060最小路径覆盖

    题意:
          有n个任务,如果时间来得及干完某些任务后还可以接着干别的任务,给一个任务清单,问最少派出去多少人能完成所有任务。


    思路: 
          比较简单的追小路径覆盖问题了,在DAG中找到最少的简单路径去覆盖所有点,结论等于n-最大匹配数,可以这样理解,最开始没有边任务都需要一个人,共n个,然后只要有一条边(干完A活来的及干B活那么连边AB),就有可能减少一个人,当A-B A-C这样的时候只能节省其中的一条,匹配也是,只能把A匹配给一个,这样说是不是很容易理解为什么最小路径覆盖的结论是n-最大匹配数了吧。


    #include<stdio.h>
    #include<string.h>


    #define N_node 500 + 10
    #define N_edge 500 * 500 + 100


    typedef struct
    {
        int time ,t,x1 ,x2 ,y1 ,y2;
    }NODE;


    typedef struct
    {
        int to ,next;
    }STAR;


    NODE node[N_node];
    STAR E[N_edge];
    int list[N_node] ,tot;
    int mkgx[N_node] ,mkdfs[N_node];


    void add(int a ,int b)
    {
        E[++tot].to = b;
        E[tot].next = list[a];
        list[a] = tot;
    }


    int DFS_XYL(int x)
    {
        for(int k = list[x] ;k ;k = E[k].next)
        {
            int to = E[k].to;
            if(mkdfs[to]) continue;
            mkdfs[to] = 1;
            if(mkgx[to] == -1 || DFS_XYL(mkgx[to]))
            {
                mkgx[to] = x;
                return 1;
            }
        }
        return 0;
    }


    int abss(int x)
    {
        return x < 0 ? -x : x;
    }


    bool ok(int a ,int b)
    {
        int t1 = abss(node[a].x1 - node[a].x2) + abss(node[a].y1 - node[a].y2);
        int t2 = abss(node[a].x2 - node[b].x1) + abss(node[a].y2 - node[b].y1);
        return node[b].t - node[a].t > t1 + t2;
    }


    int main ()
    {
        int t ,n ,i ,j ,a ,b;
        scanf("%d" ,&t);
        while(t--)
        {
            scanf("%d" ,&n);
            int tmp = 0;
            for(i = 1 ;i <= n ;i ++)
            {
                scanf("%d:%d %d %d %d %d" ,&a ,&b ,&node[i].x1 ,&node[i].y1 ,&node[i].x2 ,&node[i].y2);
                node[i].time = a * 60 + b;
                if(i != 1 && node[i].time < node[i-1].time)
                tmp ++;
                node[i].t = node[i].time + tmp * 24 * 60;
            }
            memset(list ,0 ,sizeof(list));
            tot = 1;
            for(i = 1 ;i <= n ;i ++)
            for(j = i + 1 ;j <= n ;j ++)
            {
                if(ok(i ,j)) add(i ,j);
            }
            memset(mkgx ,255 ,sizeof(mkgx));
            int Ans = 0;
            for(i = 1 ;i <= n ;i ++)
            {
                memset(mkdfs ,0 ,sizeof(mkdfs));
                Ans += DFS_XYL(i);
            }
            printf("%d " ,n - Ans);
        }
        return 0;
    }



  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/csnd/p/12062475.html
Copyright © 2011-2022 走看看