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

题目链接: POJ 2594

题目大意:给你 1~N 个点, M 条有向边。问你最少需要多少个机器人,让它们走完所有节点,不同的机器人可以走过同样的一条路,图保证为 DAG。

很明显是 最小可相交路径覆盖 问题。要先通过闭包建图后,再当作 最小不可交路径覆盖 问题 求解即可。

原因:

与 最小不可交路径覆盖 问题不同的是,两个机器人可以走相同的边,在最小覆盖的基础上如果还要走过相同的边,那么说明后一个机器人到达某一个未被走过的节点时,必须要经过某一条路,即已经走过的这条路。

比如,前一个机器人已经走了 A-->B-->C ,而后一个机器人为了到 D 点,走 A-->B-->D ,则重复的路为 A-->B 。如果我们用闭包传递后,在 A 能到达的所有节点上进行建图的话,那么 A-->B 是单独的一条, A-->C 与 A-->D 也是单独的一条,这样就使得 A 到 D 的话就不需要再经过 A-->B 了,就变成不可交的了。

同样,对于 A-->B 的点,建立 Ax-->By,变成二分图即可。(最小不可交路径覆盖问题)

代码如下:

#include<iostream>
#include<algorithm>
#include<string.h>
#define maxn 508
using namespace std;
int n,m,cnt;
int head[maxn],c[maxn];
bool flag[maxn][maxn],vis[maxn];
struct Edge
{
    int to;
    int next;
}edge[maxn*maxn*2];4387596
inline void add(int u,int v)
{
    edge[++cnt].to=v;
    edge[cnt].next=head[u];
    head[u]=cnt;
    return;
}
void floyd()
{
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(flag[i][k]&&flag[k][j]) flag[i][j]=true,add(i,j);
            }
        }
    }
    return;
}
int dfs(int u)
{
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].to;
        if(vis[v]) continue;
        vis[v]=true;
        if(c[v]==0||dfs(c[v])){
            c[v]=u;
            return 1;
        }
    }
    return 0;
}
void init()
{
    cnt=0;
    for(int i=1;i<=n;i++) {
        head[i]=c[i]=0;
        for(int j=i;j<=n;j++){
            flag[i][j]=flag[j][i]=false;
        }
    }
    return;
}
int main()
{
    //freopen("test.in","r",stdin);
    while(~scanf("%d%d",&n,&m)){
        init();
        if(n==0&&m==0) break;
        if(m==0){printf("%d\n",n );continue;}
        int A,B;
        while(m--)
        {
            scanf("%d%d",&A,&B);
            flag[A][B]=true;
            add(A,B);
        }
        floyd();
        int ans=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++) vis[j]=false;
                ans+=dfs(i);
        }
        printf("%d\n",n-ans );
    }
}

原文地址:https://www.cnblogs.com/Absofuckinglutely/p/11393631.html

时间: 2024-10-07 04:56:36

POJ 2594 (传递闭包 + 最小路径覆盖)的相关文章

POJ 2594 二分图最小路径覆盖

点击打开链接 题意:将所有点都连起来至少需要多少条路径 思路:二分图的最小路径覆盖,而最小路径覆==图的顶点数-图的最大匹配,而当初还学习过最小顶点覆盖==最大匹配,而最小顶点覆盖需要连双向边,结果除以2,那是因为1-->2时,点1和点2都已经用过,所以我在连一个相应的一条边,代表这两个点不能在用了,样例详见hdu 1054 第二组.而接下来的求最小路径覆盖的最大匹配我们就只能是单向的,这个为什么可以避免呢,因为1-->2-->3这样的话,最小路径为1,但是转化为二分图上的话,对应的点2

poj 2594 传递闭包+最大路径覆盖

由于路径可以有重复的点,所以需要将间接相连的点连接 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 //顶点编号从0开始的 7 const int MAXN=510; 8 int uN,vN;//u,v数目 9 int g[MAXN][MAXN]; 10 int linker[MAXN];

POJ 1422 DAG最小路径覆盖

求无向图中能覆盖每个点的最小覆盖数 单独的点也算一条路径 这个还是可以扯到最大匹配数来,原因跟上面的最大独立集一样,如果某个二分图(注意不是DAG上的)的边是最大匹配边,那说明只要取两个端点只要一条边即可. 故最小覆盖数还是 顶点数-最大匹配数 根据DAG建图的时候,就是DAG有边就给对应的端点建边 #include <iostream> #include <cstdio> #include <cstring> using namespace std; int d[15

POJ 2594 Treasure Exploration【传递闭包+最小路径覆盖】

大意: 有n个点,告诉你一些单向边,问多少条边能把所有的点覆盖[注意点能重复覆盖  比如4->1->2   5->3] 分析: 知识储备: 传递闭包:  所谓传递,可以这么理解,对于节点j如果i能到k并且k能到j那么i能到j,这样用像floyed就能处理出任意两个点能否到达 for(int k = 1; k <= n; k++) { for(int i = 1; i <= n; i++) { if(W[i][k]) { for(int j = 1; j <= n; j+

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

题目链接:http://poj.org/problem?id=3020 题目大意:读入一张地图.其中地图中圈圈代表可以布置卫星的空地.*号代表要覆盖的建筑物.一个卫星的覆盖范围是其周围上下左右四个点.问最少需要几个卫星才能覆盖所有建筑物. 解题思路: 有点类似POJ 1328的覆盖题,不过那题比较简单可以贪心.这题你可以YY试试. 覆盖问题其实可以用图论解决.这题就属于最小路径覆盖,手动由一个点出发连一些路径,这样Hungry就能求出最少需要多少这样的中心点,就可以达成目标了. 本题最大的疑问是

poj 3020 二分图最小路径覆盖

二分图最小路径覆盖=|v|-最大匹配.此题为有向图,切所有边正反向存了两遍,所以结果匹配数要除以2 // // main.cpp // poj3020 // // Created by Fangpin on 15/5/29. // Copyright (c) 2015年 FangPin. All rights reserved. // #include <iostream> #include <cstdio> #include <vector> #include <

Taxi Cab Scheme POJ - 2060 二分图最小路径覆盖

Running a taxi station is not all that simple. Apart from the obvious demand for a centralised coordination of the cabs in order to pick up the customers calling to get a cab as soon as possible,there is also a need to schedule all the taxi rides whi

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 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