定义:在一个有向图中,找出最少的路径,使得这些路径,经过每一个点,且每一个点只与一条路径相关联,
由上面得出:
1.一个单独的点是一个路径
2:如果有路径a,b,c。。。。f,g。a为起点,g为终点。那么a到g的点不在与其他点之间存在有向边。
最小路径覆盖=点数---最大匹配数
证明:
1 如果匹配数为0,那么图中没有边,需要n条路径
2 如果a,b之间连一条边,那么匹配数增1,需要的路径数会减少一,因为a,b之间只需要一条,那么就证明了
**********************一个最好的利用是 把点分为i与i’点,建立二分图
模板。
View Code
#include<iostream> #include<string.h> #include<stdio.h> #include<algorithm> #include<vector> #define maxn 10000 using namespace std; vector<int>node[maxn]; int mm[maxn]; int visit[maxn]; int n,m; void init() { cin>>n>>m;//输入点数,边数 for(int i=0;i<=n;i++) node[i].clear(); for(int i=0;i<m;i++) { int a,b; cin>>a>>b; node[a].push_back(b);//建边 } } int dfs(int fa) { for(int i=0;i<node[fa].size();i++) { int v=node[fa][i]; if(!visit[v]) { visit[v]=1; if(mm[v]==-1||dfs(mm[v])) { mm[v]=fa; return 1; } } } return 0; } void solve() { int cnt=0; memset(mm,-1,sizeof(mm)); for(int i=1;i<=n;i++) { memset(visit,0,sizeof(visit)); if(dfs(i))cnt++; } cout<<n-cnt<<endl;//最小路径覆盖=点数-最大匹配数 } int main() { int test; cin>>test; while(test--) { init(); solve(); } return 0; }