UVAlive 7368 Airports(建图+最小路径覆盖)

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5390

思路:先将每个点之间的最短路求出,将每条路径抽象为点,每架飞机抽象为边(对于两条路径(i,j)若飞机能在规定时间内从i到达j,则连边)。则该问题转化为用最少的边覆盖全部的点,即为最小路径覆盖。新形成的图为DAG(同样是二分图),求最大匹配数。则最小路径覆盖为节点数-最大匹配数。

#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=550;
struct Node
{
    int p,t;
    Node(int p=0,int t=0):p(p),t(t) {}
};
int n,m;
int G[maxn][maxn];
int p[maxn],c[maxn];
vector<int> g[maxn];
Node st[maxn],ed[maxn];
int f[maxn][maxn],b[maxn];
void floyd()
{
    memcpy(f,G,sizeof(G));
    for(int k=1; k<=n; k++)
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
int path(int x)
{
    for(int i=0; i<g[x].size(); i++)
    {
        int nt=g[x][i];
        if(!c[nt])
        {
            c[nt]=1;
            if(!b[nt]||(path(b[nt])))
            {
                b[nt]=x;
                return 1;
            }
        }
    }
    return 0;
}
int hungary()
{
    int ans=0;
    memset(b,0,sizeof(b));
    for(int i=1; i<=m; i++)
    {
        memset(c,0,sizeof(c));
        if(path(i)) ans++;
    }
    return m-ans;
}
void init()
{
    memset(G,0,sizeof(G));
    for(int i=0; i<=n; i++)
        for(int j=0; j<=n; j++)
            f[i][j]=INF;
    for(int i=0; i<=m; i++) g[i].clear();
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        for(int i=1; i<=n; i++)
            scanf("%d",&p[i]);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                scanf("%d",&G[i][j]);
                if(i==j) continue;
                G[i][j]+=p[j];
            }
        floyd();
        for(int i=1; i<=m; i++)
        {
            int u,v,t;
            scanf("%d%d%d",&u,&v,&t);
            st[i]=Node(u,t);
            ed[i]=Node(v,G[u][v]+t);
        }
        for(int i=1; i<=m; i++)
            for(int j=1; j<=m; j++)
            {
                if(i==j) continue;
                if(ed[i].t+f[ed[i].p][st[j].p]<=st[j].t)
                    g[i].push_back(j);
            }
        printf("%d\n",hungary());
    }
    return 0;
}
时间: 2024-10-08 06:11:06

UVAlive 7368 Airports(建图+最小路径覆盖)的相关文章

Antenna Placement POJ - 3020 二分图匹配 匈牙利 拆点建图 最小路径覆盖

题意:图没什么用  给出一个地图 地图上有 点 一次可以覆盖2个连续 的点( 左右 或者 上下表示连续)问最少几条边可以使得每个点都被覆盖 最小路径覆盖       最小路径覆盖=|G|-最大匹配数                   证明:https://blog.csdn.net/qq_34564984/article/details/52778763 证明总的来说就是尽可能多得连边 边越多 可以打包一起处理得点就越多(这里题中打包指连续得两个点只需要一条线段就能覆盖) 拆点思想   :匈牙

部落战争(建图+最小路径覆盖)

传送门 题目求最少要多少支军队可以把所有城镇覆盖完(DAG的最小不相交路径覆盖) 军队只能向下走,所以建图时就往四个方向连边,最后跑一下最小路径覆盖即可(=点数 - 二分图最大匹配) #include<bits/stdc++.h> #define N 53 using namespace std; int read() { int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} w

最小路径覆盖问题

byvoid好神啊Orz 摘自byvoid的题解 [问题分析] 有向无环图最小路径覆盖,可以转化成二分图最大匹配问题,从而用最大流解决. [建模方法] 构造二分图,把原图每个顶点i拆分成二分图X,Y集合中的两个顶点Xi和Yi.对于原图中存在的每条边(i,j),在二分图中连接边(Xi,Yj).然后把二分图最大匹配模型转化为网络流模型,求网络最大流. 最小路径覆盖的条数,就是原图顶点数,减去二分图最大匹配数.沿着匹配边查找,就是一个路径上的点,输出所有路径即可. [建模分析] 对于一个路径覆盖,有如

HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/article/details/82012572 题意: 把城市至少分成几个块,规则有三 1. A能B,B能到A,那么A,B一定要在一起. 2. 一个城市只能属于一个块. (说明了是最小不相交覆盖)3. 在一个块里的城市,任意2点之间必须有路径. 对于规则1,就是说强连通的必须在一起,所以用Tarjan

POJ 3020 Antenna Placement(二分图建图训练 + 最小路径覆盖)

题目链接:http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6692   Accepted: 3325 Description The Global Aerial Research Centre has been allotted the task of building the fifth generation of mobi

二分图最大匹配,最小路径覆盖,最小点覆盖,最大独立集,最小边覆盖与建图方法

转载请注明出处(别管写的好坏,码字也不容易):http://blog.csdn.net/hitwhacmer1 前言:         有自己写的,有摘的别人的,前面是摘的,也是无心整理,出错是难免的,反正我都不会证明,智人见智,别被我误导了. §1图论点.边集和二分图的相关概念和性质 点覆盖.最小点覆盖 点覆盖集即一个点集,使得所有边至少有一个端点在集合里.或者说是"点" 覆盖了所有"边"..极小点覆盖(minimal vertex covering):本身为点覆

训练指南 UVALive - 3126(DAG最小路径覆盖)

layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图 - 图论 - 训练指南 - 最小路径覆盖 Taxi Cab Scheme UVALive - 3126 题目大意:n个客人,从城市的不同位置出发,到达他们的目的地.已知每个人的出发时间hh:mm,出发地点(x1,y1)及目的地(x2,y2),要求使用最少的出租车接

有向无环图(DAG)的最小路径覆盖

DAG的最小路径覆盖 定义:在一个有向图中,找出最少的路径,使得这些路径经过了所有的点. 最小路径覆盖分为最小不相交路径覆盖和最小可相交路径覆盖. 最小不相交路径覆盖:每一条路径经过的顶点各不相同.如图,其最小路径覆盖数为3.即1->3>4,2,5. 最小可相交路径覆盖:每一条路径经过的顶点可以相同.如果其最小路径覆盖数为2.即1->3->4,2->3>5. 特别的,每个点自己也可以称为是路径覆盖,只不过路径的长度是0. DAG的最小不相交路径覆盖 算法:把原图的每个点

POJ 1442 Air Raid(DAG图的最小路径覆盖)

题意: 有一个城镇,它的所有街道都是单行(即有向)的,并且每条街道都是和两个路口相连.同时已知街道不会形成回路. 可以在任意一个路口放置一个伞兵,这个伞兵会顺着街道走,依次经过若干个路口. 问最少需要投放几个伞兵,使得每个路口都被伞兵拜访过.并且要满足每个路口只能被一个伞兵拜访过. 思路: 裸DAG图的最小路径覆盖. DAG图的最小路径覆盖数 = 节点数 - 二分图最大匹配 代码: vector<int> graph[125]; int cx[125],cy[125]; bool bmask[