Covering the smallest path acyclic graph

He wrote today such practice, never learned to learn on the spot!
Record it.
(Just learning, not yet fully understood, there may be an error, a mistake was found on the back to change)

definition:

Provided : directed acyclic graph
covered a minimum path : the path to find the minimum, so that the path passes through all points
the minimum path covered is divided into:
1. Minimum disjoint paths covered : As the name suggests, is the path disjoint, without the same point.
2. Minimum cover may intersect the path : is able to pass through the same point

The minimum coverage disjoint paths

Solving Methods: FIG subject to maximum matching as maximum matching of ANS, n the number of nodes is
the minimum path is (n-ans)
Principle: When the path does not match the needs of n, each matched to one side these two points corresponding to edges ,, so shrunk to a point n-1, ans edges match up, the minimum path is n-ans

Example : hdu1151
code :

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=200;
vector<int>g[maxm];
int mark[maxm];
int now[maxm];
int n,m;
int dfs(int x){
    for(int i=0;i<(int)g[x].size();i++){
        int v=g[x][i];
        if(!mark[v]){
            mark[v]=1;
            if(now[v]==0||dfs(now[v])){
                now[v]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    int T;
    cin>>T;
    while(T--){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            g[i].clear();
        }
        for(int i=1;i<=m;i++){
            int a,b;
            cin>>a>>b;
            g[a].push_back(b);
        }
        int ans=0;
        memset(now,0,sizeof now);
        for(int i=1;i<=n;i++){
            memset(mark,0,sizeof mark);
            ans+=dfs(i);
        }
        cout<<n-ans<<endl;
    }
    return 0;
}

The minimum cover disjoint paths

Examples: poj2594
solving methods: a first transfer path to increase the number floyd closure, and minimum remaining disjoint paths steps cover the same
principle: If there is an edge a-> b-> C when added, transitive closure a-> c side (regardless of whether it passes b) the rest becomes a minimum disjoint paths. (Feeling a little error)
code :

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=505;
int g[maxm][maxm];
int mark[maxm];
int now[maxm];
int n,m;
int dfs(int x){
    for(int i=1;i<=n;i++){
        if(g[x][i]&&!mark[i]){
            mark[i]=1;
            if(now[i]==0||dfs(now[i])){
                now[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    while(cin>>n>>m&&(n+m)){
        memset(g,0,sizeof g);
        for(int i=1;i<=m;i++){
            int a,b;
            cin>>a>>b;
            g[a][b]=1;
        }
        for(int k=1;k<=n;k++){//floyd传递闭包
            for(int i=1;i<=n;i++){
                if(g[i][k]==1){//减少不必要的循环
                    for(int j=1;j<=n;j++){
                        if(g[k][j]==1){
                            g[i][j]=1;
                        }
                    }
                }
            }
        }
        int ans=0;
        memset(now,0,sizeof now);
        for(int i=1;i<=n;i++){
            memset(mark,0,sizeof mark);
            ans+=dfs(i);
        }
        cout<<n-ans<<endl;
    }

    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44178736/article/details/92799080