hdu1151Air Raid poj2594Treasure Exploration题解

来源:互联网 发布:舆论是什么知乎 编辑:程序博客网 时间:2024/06/06 13:21

Air Raid
题目的意思就是给一个有向无环图,求从最少的点出发,不能重复的走完所有点。其实就是有向无环图的最小路径覆盖。
有向无环图的最小路径覆盖=节点数-匹配数(拆点)

//建图,有向无环图的最小路径覆盖=节点数-匹配数(拆点)#include <iostream>#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <stack>#include <vector>#include <string.h>#include <queue>#define msc(X) memset(X,-1,sizeof(X))#define ms(X) memset(X,0,sizeof(X))typedef long long LL;using namespace std;const int MAXN=123;bool g[MAXN][MAXN],used[MAXN];int linker[MAXN];bool dfs(int u,int n){    for(int v=1;v<=n;v++)        if(g[u][v]&&!used[v]){            used[v]=true;            if(linker[v]==-1||dfs(linker[v],n)){                linker[v]=u;                return true;            }        }    return false;}int hungary(int n){    int res=0;    msc(linker);    for(int u=1;u<=n;u++)    {        ms(used);        if(dfs(u,n)) res++;    }    return res;}int main(int argc, char const *argv[]){    int t;    scanf("%d",&t);    while(t--){        int n,m;        scanf("%d%d",&n,&m);        ms(g);        while(m--){            int u,v;            scanf("%d%d",&u,&v);            g[u][v]=true;        }        printf("%d\n",n-hungary(n) );    }    return 0;}/*211101 22 33 66 1111 711 811 95 1010 44 6331 21 32 3*/

Treasure Exploration
题目的意思就是给一个有向无环图,求从最少的点出发,走完(可重复)所有点。
和上面的题有所改变,只需把x的可达点也加到x到该点的边就可以了。

#include <iostream>#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <stack>#include <vector>#include <string.h>#include <queue>#define msc(X) memset(X,-1,sizeof(X))#define ms(X) memset(X,0,sizeof(X))typedef long long LL;using namespace std;const int MAXN=510;bool g[MAXN][MAXN];int linker[MAXN];bool used[MAXN];bool dfs(int u,int n){    for(int v=1;v<=n;v++)        if(g[u][v]&&!used[v]){            used[v]=true;            if(linker[v]==-1||dfs(linker[v],n)){                linker[v]=u;                return true;            }        }    return false;}int hungary(int n){    int res=0;    msc(linker);    for(int u=1;u<=n;u++)    {        ms(used);        if(dfs(u,n)) res++;    }    return res;}int main(int argc, char const *argv[]){    int n,m;    while(scanf("%d%d",&n,&m)==2&&(n||m)){        ms(g);        while(m--){            int a,b;            scanf("%d%d",&a,&b);            g[a][b]=true;        }        for(int k=1;k<=n;k++)            for(int u=1;u<=n;u++)                for(int v=1;v<=n;v++)                    if(g[u][k]&&g[k][v])                        g[u][v]=true;        printf("%d\n",n-hungary(n) );    }    return 0;}/*7 61 22 33 53 63 74 213 141 22 44 77 99 1010 1110 1210 1310 63 22 55 88 96 1213 141 22 44 77 99 1010 1110 610 1310 123 22 55 88 96 12*/
0 0
原创粉丝点击