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

Posted absofuckinglutely

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 );
    

 

以上是关于POJ 2594 (传递闭包 + 最小路径覆盖)的主要内容,如果未能解决你的问题,请参考以下文章

POJ2594 Treasure Exploratio —— 最小路径覆盖 + 传递闭包

poj2594最小顶点覆盖+传递闭包

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

POJ 2594 Treasure Exploration(Floyd+最小路径覆盖)

POJ 2594 Treasure Exploration 最小可相交路径覆盖

poj 2594 Treasure Exploration(最小路径覆盖,可重点)