POJ 3216 最小路径覆盖+floyd

Repairing Company

Time Limit: 1000MS   Memory Limit: 131072K
Total Submissions: 6646   Accepted: 1788

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

Source

POJ Monthly--2007.04.01, crazyb0y

题目意思:

有n个点,m个任务,点之间的权值由矩阵给出,每个任务格式为p、t、d即该任务在p点发生,t时开始,完成任务需要花费的时间d。从一个点到另一个点的花费的时间即为权值。

问完成所有的任务需要多少人。

思路:

floyd处理一下,然后当做完i任务后可以做j任务,那么连一条边i->j,最小路径覆盖即可。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 #include <cmath>
 8 #include <set>
 9 using namespace std;
10
11 #define N 25
12 #define M 205
13
14 int max(int x,int y){return x>y?x:y;}
15 int min(int x,int y){return x<y?x:y;}
16 int abs(int x,int y){return x<0?-x:x;}
17
18 struct node{
19     int p, t, d;
20 }a[M];
21
22 int map[N][N];
23 int map2[N][N];
24 vector<int>ve[M];
25 int from[M];
26 bool visited[M];
27 int n;
28
29 int march(int u){
30     int i, v;
31     for(i=0;i<ve[u].size();i++){
32         v=ve[u][i];
33         if(!visited[v]){
34             visited[v]=true;
35             if(from[v]==-1||march(from[v])){
36                 from[v]=u;
37                 return 1;
38             }
39         }
40     }
41     return 0;
42 }
43
44
45 main()
46 {
47     int i, j, k;
48     int q;
49     while(scanf("%d %d",&n,&q)==2){
50         if(n==0&&q==0) break;
51         for(i=1;i<=n;i++){
52             for(j=1;j<=n;j++){
53                 scanf("%d",&map[i][j]);
54             }
55         }
56         for(i=0;i<q;i++) scanf("%d %d %d",&a[i].p,&a[i].t,&a[i].d);
57         for(i=1;i<=n;i++){
58             for(j=1;j<=n;j++){
59                 for(k=1;k<=n;k++){
60                     if(map[j][i]!=-1&&map[i][k]!=-1){
61                         if(map[j][k]==-1) map[j][k]=map[j][i]+map[i][k];
62                         else map[j][k]=min(map[j][k],map[j][i]+map[i][k]);
63                     }
64                 }
65             }
66         }
67         for(i=0;i<q;i++) ve[i].clear();
68         for(i=0;i<q;i++){
69             for(j=0;j<q;j++){
70                 if(map[a[i].p][a[j].p]!=-1&&a[i].t+a[i].d+map[a[i].p][a[j].p]<=a[j].t){
71                     ve[i].push_back(j);
72                 //    printf("1111\n");
73                 }
74             }
75         }
76         int num=0;
77         memset(from,-1,sizeof(from));
78         for(i=0;i<q;i++){
79             memset(visited,false,sizeof(visited));
80             if(march(i)) num++;
81         }
82     //    printf("%d\n",num);
83         printf("%d\n",q-num);
84     }
85 }
时间: 2024-10-23 21:36:15

POJ 3216 最小路径覆盖+floyd的相关文章

poj2594 (最小路径覆盖 + floyd)

题目链接 题目大意: 一个有向图中, 有若干条连接的路线, 问最少放多少个机器人,可以将整个图上的点都走过. 最小路径覆盖问题. 分析: 这时最小路径覆盖问题, 最小路径覆盖 = |V| - 最大匹配数. (有关最小路径覆盖,最大匹配问题,相关概念不懂得点这里) 当然做这道题还有一个坑!! 如果有向图的边有相交的情况,那么就不能简单的对原图求二分匹配了 详细讲解看这 #include<iostream> #include<cstdio> #include<algorithm&

poj3216Repairing Company 二分匹配之最小路径覆盖+floyd

//m个任务,每个任务都有开始时间和需要花的时间,以及其在哪楼地方工作 //给出地图,每楼到另一楼的路径所花的时间 //问最少需要安排多少人能完成这些任务 //对任务和任务之间建图,如果做完任务i还能做任务j那么i-j之间建立一条边 //这样只需要找到最小路径覆盖即为最终答案 #include<cstdio> #include<iostream> #include<cstring> using namespace std ; const int maxn = 210 ;

poj 2594(最小路径覆盖)

题意:有n个点需要探索(编号从1到n),然后给出图上有m条有向边,问最少选择多少个点能遍历所有的点.注意走过的点可以重复再走. 题解:二分图求最小路径覆盖问题中点是不可以重复的,但这道题说可以重复,所以做法是可以把走过的点跳过,间接相连的点改为直接相连就可以跳过了. 特殊样例 5 4 1 2 2 3 4 2 2 5 #include <stdio.h> #include <string.h> const int N = 505; int n, m, g[N][N], vis[N],

POJ 3216 Repairing Company【Floyd + 最小路径覆盖】

大意: 有n个任务,每个任务有三个属性:所在街区,最晚开始时间,执行需要时间 告诉你一个矩阵代表街区间到达时间 告诉你每个任务的三个属性 问最少需要多少人去完成所有任务 分析: floyd处理处任意两个街区的到达时间 拆点   左边集合为n个任务    右边集合跟左边相同 i任务能够到达j任务就从左集合引一条边到右集合 求最小路径覆盖 最小路径覆盖 = n - 最大匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include

POJ 3216 Repairing Company(最小路径覆盖)

POJ 3216 Repairing Company 题目链接 题意:有m项任务,每项任务的起始时间,持续时间,和它所在的block已知,且往返每对相邻block之间的时间也知道,问最少需要多少个工人才能完成任务,即x最少是多少 思路:先floyd求出每两个block之间的最小距离,然后就是最小路径覆盖问题,一个任务之后能赶到另一个任务就建边 代码: #include <cstdio> #include <cstring> #include <algorithm> #i

POJ 2594 —— Treasure Exploration——————【最小路径覆盖、可重点、floyd传递闭包】

Treasure Exploration Time Limit:6000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2594 Description Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploratio

POJ - 3216 Repairing Company 二分图 最小路径覆盖

题目大意:有一个人开了一间维修店.某天,该维修店接收到了Q个任务,这Q个任务分布在M个城市中.每个任务有三个值,分别是所在城市,起始时间,维修时间. 现在给出M个城市的路线图,路线对应的是从某城市到某城市的所需时间. 问至少要派多少个维修人员才能完成这Q个任务 解题思路:现将能联通的城市联通起来,用floyd求出城市之间的时间数 接着就要找关系了,如果 起始时间 + 维修时间 + 两个城市来往的时间 <= 另外一个任务的起始时间 就表示该任务做完后可以接着做下一个任务,这样关系就明确了 现在要求

POJ3216 Repairing Company【二分图最小路径覆盖】【Floyd】

题目链接: http://poj.org/problem?id=3216 题目大意: 有Q个地点,告诉你Q个地点之间的相互距离(从i地点赶到j地点需要的时间).有M项任务, 给你M项任务所在的地点block.开始时间start和任务完成需要时间time.一个工人只有在 他准备完成的下一项任务开始之前完成手上的任务,然后在下一项任务开始之前赶到下一项 任务的地点,才能完成这两项任务.问:最少需要多少个工人来完成这M项任务. 思路: 先用Floyd算出Q个地点之间相互最短距离.然后建立一个二分图,每

POJ 2594 Treasure Exploration(最小路径覆盖变形)

POJ 2594 Treasure Exploration 题目链接 题意:有向无环图,求最少多少条路径能够覆盖整个图,点能够反复走 思路:和普通的最小路径覆盖不同的是,点能够反复走,那么事实上仅仅要在多一步.利用floyd求出传递闭包.然后依据这个新的图去做最小路径覆盖就可以 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using names