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

POJ 3216 Repairing Company

题目链接

题意:有m项任务,每项任务的起始时间,持续时间,和它所在的block已知,且往返每对相邻block之间的时间也知道,问最少需要多少个工人才能完成任务,即x最少是多少

思路:先floyd求出每两个block之间的最小距离,然后就是最小路径覆盖问题,一个任务之后能赶到另一个任务就建边

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int N = 25;
const int M = 205;
const int INF = 0x3f3f3f3f;

int n, m, q[N][N];
vector<int> g[M];

int in[M], s[M], d[M];

bool judge(int i, int j) {
	return s[i] + d[i] + q[in[i]][in[j]] <= s[j];
}

int left[M], vis[M];

bool dfs(int u) {
	for (int i = 0; i < g[u].size(); i++) {
		int v = g[u][i];
		if (vis[v]) continue;
		vis[v] = 1;
		if (left[v] == -1 || dfs(left[v])) {
			left[v] = u;
			return true;
		}
	}
	return false;
}

int hungary() {
	int ans = 0;
	memset(left, -1, sizeof(left));
	for (int i = 0; i < m; i++) {
		memset(vis, 0, sizeof(vis));
		if (dfs(i)) ans++;
	}
	return ans;
}

int main() {
	while (~scanf("%d%d", &n, &m) && n) {
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++) {
				scanf("%d", &q[i][j]);
				if (q[i][j] == -1) q[i][j] = INF;
			}
		for (int k = 1; k <= n; k++) {
			for (int i = 1; i <= n; i++) {
				for (int j = 1; j <= n; j++) {
					q[i][j] = min(q[i][j], q[i][k] + q[k][j]);
				}
			}
		}
		for (int i = 0; i < m; i++) {
			g[i].clear();
			scanf("%d%d%d", &in[i], &s[i], &d[i]);
			for (int j = 0; j < i; j++) {
				if (judge(i, j))
					g[i].push_back(j);
				if (judge(j, i))
					g[j].push_back(i);
			}
		}
		printf("%d\n", m - hungary());
	}
	return 0;
}
时间: 2024-10-27 05:49:45

POJ 3216 Repairing Company(最小路径覆盖)的相关文章

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

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

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

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

POJ 3216 Repairing Company

题目链接 http://poj.org/problem?id=3216 题目解释 题意:莉莉是一家维修公司,服务这个城市的 Q 块.有一天,公司收到M修复任务,其中第 i 个发生在Pi块,对任何修理工的到来的最后到来期限的Ti,就是它的起始时间,并需要一个修理工  Di  时间完成.修理工完成当前单个任务,必须在移动(移动到下一个块需要消耗时间)到下一个完成下一个任务.有地图在手,莉莉想知道最少的修理工,才能够完成金今天所有的任务. 输入:首先输入两个数 Q, M, 代表有 Q 个块, M个任务

POJ 2594 传递闭包的最小路径覆盖

Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 7171   Accepted: 2930 Description Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploration? Have you ever explored

poj 3020 Antenna Placement (最小路径覆盖)

链接:poj 3020 题意:一个矩形中,有n个城市'*','o'表示空地,现在这n个城市都要覆盖无线,若放置一个基站, 那么它至多可以覆盖本身和相邻的一个城市,求至少放置多少个基站才能使得所有的城市都覆盖无线? 思路:求二分图的最小路径覆盖(无向图) 最小路径覆盖=点数-最大匹配数 注:因为为无向图,每个顶点被算了两次,最大匹配为原本的两倍, 因此此时最小路径覆盖=点数-最大匹配数/2 #include<stdio.h> #include<string.h> int edge[4

[POJ] 1422 Air Raid(最小路径覆盖)

题目地址:http://poj.org/problem?id=1422 一个地图上有n个小镇,以及连接着其中两个小镇的有向边,而且这些边无法形成回路.现在选择一些小镇空降士兵(1个小镇最多1个士兵),士兵能沿着边走到尽头,问最少空降几个士兵,能遍历完所有的小镇.最小路径覆盖问题.先拆点,将每个点分为两个点,左边是1到n个点,右边是1到n个点然后每一条有向边对应左边的点指向右边的点 因为最小路径覆盖 = 节点数 - 最大匹配数,所以匈牙利算法求一下二分图最大匹配就能得出结果了. 1 #includ

POJ 1548 Robots(最小路径覆盖)

POJ 1548 Robots 题目链接 题意:乍一看还以为是小白上那题dp,其实不是,就是求一共几个机器人可以覆盖所有路径 思路:最小路径覆盖问题,一个点如果在另一个点右下方,就建边,然后跑最小路径覆盖即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 25 * 25; in

POJ 1422 二分图(最小路径覆盖)

Air Raid Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7278   Accepted: 4318 Description Consider a town where all the streets are one-way and each street leads from one intersection to another. It is also known that starting from an i

POJ 2594 (传递闭包 + 最小路径覆盖)

题目链接: POJ 2594 题目大意:给你 1~N 个点, M 条有向边.问你最少需要多少个机器人,让它们走完所有节点,不同的机器人可以走过同样的一条路,图保证为 DAG. 很明显是 最小可相交路径覆盖 问题.要先通过闭包建图后,再当作 最小不可交路径覆盖 问题 求解即可. 原因: 与 最小不可交路径覆盖 问题不同的是,两个机器人可以走相同的边,在最小覆盖的基础上如果还要走过相同的边,那么说明后一个机器人到达某一个未被走过的节点时,必须要经过某一条路,即已经走过的这条路. 比如,前一个机器人已