The main effect of the topic:
Given a direction graph g= (v,e).
Set P is a simple set of paths for G.
If every vertex in V happens to be on one of P's paths,
It is said that P is a path cover of G. The path in P can start at any vertex of V, and the length is arbitrary, in particular, it can be 0. The minimum path cover of G is the path cover with the least number of path bars in G. An effective algorithm is designed to find a minimal path overlay for a direction-free graph G.
Set v={1,2, ..., n}, with M Edge,
The Construction Network g1= (V1,E1) is as follows:
The capacity of each edge is 1. Find the maximum flow of the network G1 (0 x, 0 y).
1<=n<=150,1<=m<=6000
P top vertices do not intersect :
Create a source point s with a meeting point T,
S to all points, the edge is 1,s–>i;
All points to T even one side, the edge is 1,i+n–>t;
The beginning of any One Direction edge is connected to the end point, and the edge right is 1,
x–>y;
The above operation is to build a reverse edge.
And then run out of Max Stream Max,
And then you know:
Minimum path overlay ans=n-maximum matching number max
And then output the solution,
Just record which point each point is next to, and which point arrives and then recursively code:
#include <bits/stdc++.h> #define INF 23333333 #define N #define M 60005 using namespace std;
Queue <int> Q;
int a[m],d[n],p[n],q[n],c[n],ls[n],to[m],next[m],cnt=1,n,m,s,t,x,y;
void Add (int u,int v,int W) {to[++cnt]=v; a[cnt]=w; next[cnt]=ls[u]; ls[u]=cnt;}
BOOL BFs () {memset (d,0,sizeof (d));
while (Q.size ()) Q.pop (); Q.push (s);
D[s]=1;
while (Q.size ()) {int U=q.front ();
Q.pop ();
for (int i=ls[u]; i!=0 i=next[i]) if (a[i) &&!d[to[i]) {Q.push (to[i));
d[to[i]]=d[u]+1;
if (to[i]==t) return 1;
} return 0;
int dinic (int dep,int flow) {if (dep==t) return flow;
int rest=flow,rp=0; for (int i=ls[dep]; I && rest; I=next[i]) if (A[i] && d[to[i]]==d[dep]+1) {rp=dinic (
To[i],min (Rest,a[i]));
if (!RP) d[to[i]]=0; if (RP && dep!=s && to[i]!=t) {p[dep]=to[i]-n;
Q[TO[I]-N]=DEP;
} A[I]-=RP;
A[I^1]+=RP;
REST-=RP;
return flow-rest;
} void work (int dep) {if (!DEP) return;
if (Q[DEP]!=DEP) work (Q[DEP]);
C[dep]=1;
printf ("%d", DEP);}
int main () {scanf ("%d%d", &n,&m);
for (int i=1; i<=m; i++) {scanf ("%d%d", &x,&y);
Add (x,y+n,1);
Add (y+n,x,0);
} s=0,t=2*n+1;
for (int i=1; i<=n; i++) {p[i]=q[i]=i;
Add (s,i,1), add (i,s,0);
Add (i+n,t,1), add (t,i+n,0);
int flow=0,ans=0;
Memset (C,0,sizeof (c));
while (BFS ()) {while (Flow=dinic (S,inf)) Ans+=flow;
for (int i=n; i>=1; i--) if (p[i]==i &&!c[i)) {work (i);
printf ("\ n");
printf ("%d\n", N-ans); ReTurn 0;
}