zoukankan      html  css  js  c++  java
  • POJ 3216 Repairing Company (Floyd + 二分图)

    题目链接 http://poj.org/problem?id=3216

    题目解释

    题意:莉莉是一家维修公司,服务这个城市的 Q 块。有一天,公司收到M修复任务,其中第 i 个发生在Pi块,对任何修理工的到来的最后到来期限的Ti,就是它的起始时间,并需要一个修理工  Di  时间完成。修理工完成当前单个任务,必须在移动(移动到下一个块需要消耗时间)到下一个完成下一个任务。有地图在手,莉莉想知道最少的修理工,才能够完成金今天所有的任务。

    输入:首先输入两个数 Q, M, 代表有 Q 个块, M个任务,下面输入 QxQ 个数,即一个矩阵,Qij 表示第i个块 到 第j个块的 时间,如果是-1,则表示他们之间没有路;

    接下来是 M 行,每行3 个数,分别是Pi, Ti,D

    输出 最少的修理工

    思路分析

    分析:首先根据 地图 求出来 任意两个块之间的最短路径, 之后 根据 任务,求任务的二分图最大匹配,得出 最小路径覆盖即可;

    如何建二分图:如果 Di + Qij <= Tj,即当前任务结束时间加上路径时间不大于下一个任务开始时间 即建边

    代码:

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <cctype>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <queue>
     9 #include <stack>
    10 #include <map>
    11 
    12 using namespace std;
    13 
    14 const int INF=0x3f3f3f3f;
    15 #define maxn 300
    16 int edge[maxn][maxn], q, m;
    17 bool visit[maxn], g[maxn][maxn];
    18 int match[maxn];
    19 struct Task
    20 {
    21     int id, s, e;
    22 }task[maxn];
    23 void Floyd()
    24 {
    25     for(int i = 1; i <= q; i++)
    26     {
    27         for(int j = 1; j <= q; j++)
    28         {
    29             for(int k = 1; k <= q; k++)
    30             {
    31                 if (edge[j][i] + edge[i][k] < edge[j][k])
    32                     edge[j][k] = edge[j][i] + edge[i][k];
    33             }
    34         }
    35     }
    36 }
    37 
    38 bool dfs(int num)
    39 {
    40     int u = task[num].id, t1 = task[num].s, d1 = task[num].e;
    41     for(int i = 0; i < m; i++)
    42     {
    43         int v = task[i].id, t2 = task[i].s, d2 = task[i].e;
    44         //printf("edge = %d m = %d d1 = %d t2 = %d
    ", edge[u][v], m, d1, t2);
    45         if (edge[u][v]!=INF && !visit[i] && t1+d1+edge[u][v]<=t2)
    46         {
    47             //puts("hehe");
    48             visit[i] = true;
    49             if(match[i] == -1 || dfs(match[i]))
    50             {
    51                 match[i] = num;
    52                 return true;
    53             }
    54         }
    55     }
    56     return false;
    57 }
    58 int Hungary()
    59 {
    60     int ans = 0;
    61     memset(match, -1, sizeof(match));
    62     for(int i = 0; i < m; i++)
    63     {
    64         memset(visit, false, sizeof(visit));
    65         if(dfs(i))
    66             ans++;
    67         //printf("ans = %d", ans);
    68     }
    69     return ans;
    70 }
    71 int main()
    72 {
    73     int p, d, t;
    74     while(scanf("%d %d", &q, &m) && q+m)
    75     {
    76         for(int i = 1; i <= q; i++)
    77         {
    78             for(int j = 1; j <= q; j++)
    79             {
    80                 scanf("%d", &edge[i][j]);
    81                 if(edge[i][j] == -1)
    82                     edge[i][j] = INF;
    83             }
    84         }
    85         Floyd();
    86         for(int i = 0; i < m; i++)
    87         {
    88             scanf("%d %d %d", &p, &t, &d);
    89             task[i].id = p; task[i].s = t; task[i].e = d;
    90         }
    91         printf("%d
    ", m - Hungary());
    92     }
    View Code
  • 相关阅读:
    微信公众平台开发教程(一) 微信公众账号注册流程
    DNS----域名解析系统
    C#编程总结(九)字符编码
    向大神学习
    C# 正则表达式
    js 正则表达式 取反
    H5 打开App
    Fiddler 过滤器的使用
    Fiddler 默认不能抓取页面信息的问题
    js 元素Dom新建并插入页面createElement
  • 原文地址:https://www.cnblogs.com/tenlee/p/4426188.html
Copyright © 2011-2022 走看看