概述:
在一个有向图G中,如果在图G中有一些路径,使之覆盖了图G中的所有顶点,且任何一个顶点有且只有一条路径与之关联,那么最小路径覆盖就是最少条数的路径。
ps:一个单独的顶点也是一条路径。
性质:
无圈有向图G的最小路径覆盖数=V-与其对应的二分图G‘的最大匹配数
ps:对于一个有向图G=(V,E),对应的二分图G‘=(V,E,V)的构建方式为:对G的有向边(u,v),在G‘中有对应的无向边(u,v);
二分图匈牙利算法点击打开链接,每条路径的还原整体思路是找到路径的起始顶点;
代码:(匈牙利算法+每条路径的还原)
int n=m;
//通过DFS寻找增广路
bool dfs(int v){
for (int j=1;j<=m;j++)
{
if (G[v][j] && !used[j])
{
used[j]=1;
if (match[j]==0 || find(match[j]))
{
match[j]=v;
return true;
}
}
}
return false;
}
//求解二分图的最大匹配
int bipartite_matching()
{
int res=0;
for (int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
if(dfs(v))
{
res++;
}
}
}
//路径还原
void path()
{
memset(used,0,sizeof(used));
for(int j=1;j<=m;j++)
{
if(match[j])
{
used[match[j]]++;//找路径的起点
used[j]=used[match[j]]+1;//找路径的起点
next[match[j]]=j;
//匹配边的输出:cout<<match[j]<<"->"<<j<<endl;
}
}
//输出路径
for(int i=1;i<=n;i++)
{
if(used[i]==1)//编号是1的显然为路径的起点
{
cout<<i;
j=next[i];
while(j)
{
cout<<' '<<j;
j=next[j];
}
cout<<endl;
}
}
//对无匹配的顶点输出,作为孤立路径
for(int i=1;i<=n;i++)
if(used[i]==0)
cout<<i<<endl;
}