网络流四·最小路径覆盖
每个点拆成两个点限流为1.
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxv = 1010; 4 const int maxe = 20010; 5 const int inf = 0x3f3f3f3f; 6 struct Edge{ 7 int u, v, nex; 8 int cap, flow; 9 Edge(int u=0, int v=0, int nex=0, int cap=0, int flow=0): 10 u(u), v(v), nex(nex), cap(cap), flow(flow){} 11 }e[maxe<<1]; 12 int head[maxv]; 13 int cnt; 14 void init(){ 15 memset(head, -1, sizeof(head)); 16 cnt = 0; 17 } 18 19 void add(int u, int v, int cap){ 20 e[cnt] = Edge(u, v, head[u], cap, 0); 21 head[u] = cnt++; 22 e[cnt] = Edge(v, u, head[v], 0, 0); 23 head[v] = cnt++; 24 } 25 26 int d[maxv], num[maxv], cur[maxv], p[maxv]; 27 int vis[maxv]; 28 int S, T; 29 int N; 30 31 void bfs(){ 32 memset(d, -1, sizeof(d)); 33 memset(vis, 0, sizeof(vis)); 34 queue<int> q; 35 q.push(T); 36 vis[T] = 1; 37 d[T] = 0; 38 while(!q.empty()){ 39 int u = q.front(); 40 q.pop(); 41 for(int i = head[u]; ~i; i = e[i].nex){ 42 int id = i&(-2); //正边 43 int v = e[id].u; 44 if(!vis[v] && e[id].cap > e[id].flow){ 45 vis[v] = 1; 46 d[v] = d[u] + 1; 47 q.push(v); 48 } 49 } 50 } 51 } 52 53 int augment(){ 54 int u = T; 55 int a = inf; 56 while(u!=S){ 57 int id = p[u]; 58 a = min(a, e[id].cap - e[id].flow); 59 u = e[id].u; 60 } 61 u = T; 62 while(u!=S){ 63 int id = p[u]; 64 e[id].flow += a; 65 e[id^1].flow -= a; 66 u = e[id].u; 67 } 68 return a; 69 } 70 71 int ISAP(){ 72 bfs(); 73 int flow = 0; 74 memset(num, 0, sizeof(num)); 75 for(int i = 0; i < N; i++){ 76 cur [i] = head[i]; 77 if(~d[i]) num[d[i]]++; 78 } 79 int u = S; 80 while(d[S] < N){ 81 if(u == T){ 82 flow += augment(); 83 u = S; 84 } 85 int ok = 0; 86 for(int i = cur[u]; ~i; i = e[i].nex){ 87 int v = e[i].v; 88 if(d[u] == d[v]+1 && e[i].cap > e[i].flow){ 89 p[v] = i; 90 ok = 1; 91 cur[u] = i; 92 u = v; 93 break; 94 } 95 } 96 if(!ok){ 97 int m = N-1; 98 for(int i = head[u]; ~i; i = e[i].nex){ 99 if(e[i].cap > e[i].flow && ~d[e[i].v]) m = min(m, d[e[i].v]); 100 } 101 if(--num[d[u]] == 0) break; 102 num[d[u]=m+1]++; 103 cur[u] = head[u]; 104 if(u != S) u = e[p[u]].u; 105 } 106 } 107 return flow; 108 } 109 110 int main(){ 111 init(); 112 int n, m; 113 scanf("%d %d", &n, &m); 114 int u, v; 115 for(int i = 0; i < m; i++){ 116 scanf("%d %d", &u, &v); 117 add(2*u-1, 2*v, 1); 118 } 119 S = 0; 120 T = 2*n+1; 121 N = T+1; 122 for(int i = 1; i <= n; i++){ 123 add(S, 2*i-1, 1); 124 add(2*i, T, 1); 125 } 126 int ans = ISAP(); 127 printf("%d ", n-ans); 128 }