poj 2594 Treasure Exploration 可重复覆盖的二分图最小覆盖路径

来源:互联网 发布:nsga2算法讲解 编辑:程序博客网 时间:2024/05/22 01:47

             题意:给出一个图,有N个点有宝藏,M条单向边,求用最少的机器人去挖宝藏。

             思路:注意到You should notice that the roads of two different robots may contain some same point。说明有些点可以重复经过,所以只要考虑路径的两个端点即可,用floyd求传递闭包。

     代码:

#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#include<queue>#include<vector>#include<iostream>#define Maxn 500+10#define clr(a,b) memset(a,b,sizeof(a))using namespace std;int vis[Maxn],g[Maxn][Maxn],n,m,mat[Maxn],x,y;void floyd(){    for(int k=0;k<n;k++)       for(int i=0;i<n;i++)          for(int j=0;j<n;j++)             if(g[i][k]&&g[k][j])                g[i][j]=1;}bool find(int x){    for(int i=0;i<n;i++)    {        if(!vis[i]&&g[x][i])        {            vis[i]=1;            if(mat[i]==-1||find(mat[i]))            {                mat[i]=x;                return 1;            }        }    }    return 0;}int Hungary(int n){    int Max=0;    clr(mat,-1);    for(int i=0;i<n;i++)    {        clr(vis,0);        if(find(i)) Max++;    }    return Max;}int main(){    while(~scanf("%d %d",&n,&m))    {        if(n==0&&m==0) break;        if(m==0) { printf("%d\n",n);continue;}        clr(g,0);        for(int i=0;i<m;i++)           {               scanf("%d %d",&x,&y);               g[x-1][y-1]=1;           }        floyd();        printf("%d\n",n-Hungary(n));    }    return 0;}



原创粉丝点击