zoukankan      html  css  js  c++  java
  • poj 3216 Repairing Company(最短路Floyd + 最小路径覆盖 + 构图)

    http://poj.org/problem?id=3216

    Repairing Company
    Time Limit: 1000MS   Memory Limit: 131072K
    Total Submissions: 6776   Accepted: 1822

    Description

    Lily runs a repairing company that services the Q blocks in the city. One day the company receives M repair tasks, the ith of which occurs in block pi, has a deadline ti on any repairman’s arrival, which is also its starting time, and takes a single repairman di time to finish. Repairmen work alone on all tasks and must finish one task before moving on to another. With a map of the city in hand, Lily want to know the minimum number of repairmen that have to be assign to this day’s tasks.

    Input

    The input contains multiple test cases. Each test case begins with a line containing Q and M (0 < Q ≤ 20, 0 < M ≤ 200). Then follow Q lines each with Q integers, which represent a Q × Q matrix Δ = {δij}, where δij means a bidirectional road connects the ith and the jth blocks and requires δij time to go from one end to another. If δij = −1, such a road does not exist. The matrix is symmetric and all its diagonal elements are zeroes. Right below the matrix are M lines describing the repairing tasks. The ith of these lines contains piti and di. Two zeroes on a separate line come after the last test case.

    Output

    For each test case output one line containing the minimum number of repairmen that have to be assigned.

    Sample Input

    1 2
    0
    1 1 10
    1 5 10
    0 0

    Sample Output

    2

    题目大意:Lily管理q个地方(q*q的矩阵,maps[i][j]表示地点i到j花费的时间),她接到m个任务

    每个任务i,该任务的执行的地点为pi,执行人员到达花费时间ti(也是该任务i开始的时间),完成该任务

    花费时间di,执行人员完成了上一个任务下能去做下一个任务(即执行人员要想做第j个任务,他完成上一

    个任务i花的所有时间+到达第j个任务发生的地点所花的时间<=第j个任务开始的时间);求最少需要多少

    执行人员去执行这m个任务


    用Floyd来找到地点i到地点j花费的最少时间即最短路(即可以缩短执行人员从i地到j地在路上的时间)

    然后用二分匹配,注意二分图的X集合和Y集合都是任务的编号,而不是任务执行的地点如果第i个任务完成

    后还能做第j个任务,则i与j之间有一条连线G[i][j] = 1

    接下来就是二分匹配的最小覆盖路经问题了

    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<stdlib.h>
    #include<algorithm>
    #define N 310
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    struct node
    {
        int p, t, d;
    }node[N];
    
    int G[N][N], maps[30][30], vis[N], used[N];
    int m, q;
    
    bool Find(int u)
    {
        int i;
        for(i = 1 ; i <= m ; i++)
        {
            if(!vis[i] && G[u][i])
            {
                vis[i] = 1;
                if(!used[i] || Find(used[i]))
                {
                    used[i] = u;
                    return true;
                }
            }
        }
        return false;
    }
    
    void Floyd()
    {
        int i, j, k;
        for(k = 1 ; k <= q ; k++)
        {
            for(i = 1 ; i <= q ; i++)
            {
                for(j = 1 ; j <= q ; j++)
                {
                    if(maps[i][k] + maps[k][j] < maps[i][j])
                        maps[i][j] = maps[i][k] + maps[k][j];
                }
            }
        }
    }
    
    int main()
    {
        int i, j;
        while(scanf("%d%d", &q, &m), q + m)
        {
            memset(G, 0, sizeof(G));
            for(i = 1 ; i <= q ; i++)
            {
                for(j = 1 ; j <= q ; j++)
                  {
                      scanf("%d", &maps[i][j]);
                      if(maps[i][j] == -1)
                        maps[i][j] = INF;
                  }
            }
            for(i = 1 ; i <= m ; i++)
                scanf("%d%d%d", &node[i].p, &node[i].t, &node[i].d);
            Floyd();
            for(i = 1 ; i <= m ; i++)
            {
                for(j = 1 ; j <= m ; j++)
                {
                    if(i == j)continue;
                    if(node[i].d + maps[node[i].p][node[j].p] + node[i].t <= node[j].t)
                        G[i][j] = 1;//****注意此处二分图的两个集合元素是任务的编号而不是地点block
                }
            }
            int ans = 0;
            memset(used, 0, sizeof(used));
            for(i = 1 ; i <= m ; i++)
            {
                memset(vis, 0, sizeof(vis));
                if(Find(i))
                    ans++;
            }
            printf("%d
    ", m - ans);
        }
        return 0;
    }
     
  • 相关阅读:
    数据仓库
    数据库事务隔离级别与锁
    并发包之Future:代码级控制超时时间
    axis2 webservice 发布、调用与项目集成
    配置远程控制
    解决局部刷新的问题
    Sharepoint 2013 搜索高级配置(Search Scope)
    重启IIS报错:IIS 服务或万维网发布服务,或者依赖这 服务可能在启动期间发生错误或者已禁用
    错误提示:此产品的试用期已经结束
    Sharepoint 2013 启用搜做服务
  • 原文地址:https://www.cnblogs.com/qq2424260747/p/4840570.html
Copyright © 2011-2022 走看看