HDU 3991 Harry Potter and the Present II(Floyd+DAG最小路径覆盖)

本文介绍了一个基于图论的最大匹配算法解决礼物配送问题的方法。通过构建一个图模型,并使用弗洛伊德算法进行路径寻优,确保每个城市的礼物都能在指定时间送达。最终,通过最小化额外需求的人数来优化配送效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:一幅图上有N个点,M条边,边的权值表示通过这条边所需要的时间。有Q个任务,每次任务以Ci,Ti的形式给出Ci表示城市编号,Ti表示任务需要在Ti这个时间点完成.现在你拥有一个人,问至少还需要几个人才能完成所有城市给定时间上的任务。每个人都可以在任何时间点出现在任何城市

思路:和POJ3216一样的做法..


#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=1000+5;
#define inf 1e9
#define INF 1LL<<60
struct Max_Match
{
    int n,m;
    vector<int> g[maxn];
    bool vis[maxn];
    int left[maxn];

    void init(int n)
    {
        this->n=n;
		//this->m=m;
        for(int i=1; i<=n; ++i) g[i].clear();
        memset(left,-1,sizeof(left));
    }

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

    int solve()
    {
        int ans=0;
        for(int i=1; i<=n; ++i)
        {
            memset(vis,0,sizeof(vis));
            if(match(i)) ++ans;
        }
        return ans;
    }
}MM;
int cas=1,T;
int n,m,Q;
struct Node
{
	int p,t;
}node[maxn];
long long d[maxn][maxn];
void floyd()
{
	for (int k = 0;k<n;k++)
		for (int i = 0;i<n;i++)
			for (int j = 0;j<n;j++)
				if (d[i][k]<INF && d[k][j]<INF)
					d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
bool check(int i,int j)
{
	return node[i].t+d[node[i].p][node[j].p]<=node[j].t;
}
int main()
{
	scanf("%d",&T);
	while (T--)
	{
		scanf("%d%d%d",&n,&m,&Q);
		for (int i = 0;i<=n;i++)
			for (int j = 0;j<=n;j++)
			{
		         d[i][j] = i==j?0:INF;
			}
		while (m--)
		{
			int u,v;
			long long di;
			scanf("%d%d%I64d",&u,&v,&di);
			d[u][v]=d[v][u]=di;
		}
		floyd();
		MM.init(Q);
		for (int i = 1;i<=Q;i++)
			scanf("%d%d",&node[i].p,&node[i].t);
		for (int i = 1;i<=Q;i++)
			for (int j = 1;j<=Q;j++)
				if (i!=j && check(i,j))
				{
					MM.g[i].push_back(j);
				}
		printf("Case %d: %d\n",cas++,Q-MM.solve()-1);
	}
    return 0;
}

Description

Harry and his friends buy a lot of presents now, but they immediately find they had bought too many presents, so they decide to distribute them to the magicians who need them. 
To simplify the problem, here we assume the magic world has N cities and M roads, and there are Q requests, at time Ti, someone at city Pi need a present. After planning the route for a while, Harry realizes he can’t do it by himself, he need to find some friends to help him. But the new question is, how many friends Harry should ask at least? We can assume every magician can choose the original city and time to begin his/her journey, and all of them have the same speed, one unit distance per unit time. And if he/she is exactly in city Pi at time Ti, he/she will give the present in a wink, yes, as you see, they are magicians. 
 

Input

The first line contains a single integer T, indicating the number of test cases. 
Each test case begins with three integers N, M, Q. Then M lines following, each line contains three integers Ai, Bi, Ci, describing an undirected road. Then Q lines following, each line contains two integers Pi, Ti, describing a request. 

Technical Specification 

1. 1 <= T <= 50 
2. 1 <= N <= 100 
3. 1 <= M, Q <= 1 000 
4. 0 <= Ai, Bi, Pi < N, Ai != Bi 
5. 0 <= Ci, Ti <= 1 000 000 000 
 

Output

For each test case, output the case number first, then the least friend number. 
 

Sample Input

2 2 1 2 0 1 1 0 1 1 2 2 1 2 0 1 2 0 1 1 2
 

Sample Output

Case 1: 0 Case 2: 1

Hint

If you can’t figure out the sample, think twice whether you have forgotten someone named Harry Potter. 
         
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值