zoukankan      html  css  js  c++  java
  • Repairing Company(poj 3216)

    题目大意:

    有Q个地点,告诉你Q个地点之间的相互距离(从i地点赶到j地点需要的时间)。有M项任务,

    给你M项任务所在的地点block、开始时间start和任务完成需要时间time。一个工人只有在

    他准备完成的下一项任务开始之前完成手上的任务,然后在下一项任务开始之前赶到下一项

    任务的地点,才能完成这两项任务。问:最少需要多少个工人来完成这M项任务。

    /*
      对于这类二分图的最小路径覆盖,我是这么理解的:
      那这道题来说,我们可以先假设一共需要m个工人,然后经过二分图匹配,
      每匹配一对,说明有两项任务可以由一个工人完成,m就减1,最后,剩下
      的m即为所求
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define M 210
    #define N 22
    using namespace std;
    int map[N][N],used[M],belong[M],a[M][M],q,m;
    struct node
    {
        int pos,begin,end;
    };node e[M];
    void Floyed()
    {
        for(int k=1;k<=q;k++)
          for(int i=1;i<=q;i++)
            for(int j=1;j<=q;j++)
              if(i!=j&&i!=k&&j!=k)
                map[i][j]=min(map[i][k]+map[k][j],map[i][j]);
    }
    int find(int i)
    {
        for(int j=1;j<=m;j++)
          if(!used[j]&&a[i][j])
          {
              used[j]=1;
              if(!belong[j]||find(belong[j]))
              {
                  belong[j]=i;
                  return 1;
              }
          }
        return 0;
    }
    int main()
    {
        while(1)
        {
            memset(map,0x3f3f3f3f,sizeof(map));
            memset(used,0,sizeof(used));
            memset(belong,0,sizeof(belong));
            memset(a,0,sizeof(a));
            scanf("%d%d",&q,&m);
            if(q==0&&m==0)break;
            for(int i=1;i<=q;i++)
              for(int j=1;j<=q;j++)
              {
                  int x;
                  scanf("%d",&x);
                  if(x!=-1)
                  map[i][j]=map[j][i]=x;
              }
            Floyed();
            for(int i=1;i<=m;i++)
            {
                int x;
                scanf("%d%d%d",&e[i].pos,&e[i].begin,&x);
                e[i].end=e[i].begin+x;
            }
              
            for(int i=1;i<=m;i++)
              for(int j=1;j<=m;j++)
                if(i!=j&&e[j].begin-e[i].end>=map[e[i].pos][e[j].pos])
                  a[i][j]=1;
            int tot=0;
            for(int i=1;i<=m;i++)
              if(find(i))
              {
                  memset(used,0,sizeof(used));
                  tot++;
              }
            printf("%d
    ",m-tot);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Failed to parse PID from file /run/nginx.pid: Invalid argument
    Ubuntu16.04环境下bashrc文件位置
    virtualenvwrapper.sh报错: There was a problem running the initialization hooks.解决
    pip安装virtualenvwrapper报错的解决办法
    争鸣|函数性质的综合应用辨析
    总结|静雅斋之2020高考备考回顾总结
    2020年全国卷Ⅱ卷文科数学图片版
    奇怪|说好的求最大值变成了求最小值
    探究|平面向量探究题
    平面向量错误收集
  • 原文地址:https://www.cnblogs.com/harden/p/5633998.html
Copyright © 2011-2022 走看看