网络流四·最小路径覆盖 HihoCoder - 1394
Posted yijiull
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流四·最小路径覆盖 HihoCoder - 1394相关的知识,希望对你有一定的参考价值。
网络流四·最小路径覆盖
每个点拆成两个点限流为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 while(!q.empty()){ 38 int u = q.front(); 39 q.pop(); 40 for(int i = head[u]; ~i; i = e[i].nex){ 41 int id = i&(-2); //正边 42 int v = e[id].u; 43 if(!vis[v] && e[id].cap > e[id].flow){ 44 vis[v] = 1; 45 d[v] = d[u] + 1; 46 q.push(v); 47 } 48 } 49 } 50 } 51 52 int augment(){ 53 int u = T; 54 int a = inf; 55 while(u!=S){ 56 int id = p[u]; 57 a = min(a, e[id].cap - e[id].flow); 58 u = e[id].u; 59 } 60 u = T; 61 while(u!=S){ 62 int id = p[u]; 63 e[id].flow += a; 64 e[id^1].flow -= a; 65 u = e[id].u; 66 } 67 return a; 68 } 69 70 int ISAP(){ 71 bfs(); 72 int flow = 0; 73 memset(num, 0, sizeof(num)); 74 for(int i = 0; i < N; i++){ 75 cur [i] = head[i]; 76 if(~d[i]) num[d[i]]++; 77 } 78 int u = S; 79 while(d[S] < N){ 80 if(u == T){ 81 flow += augment(); 82 u = S; 83 } 84 int ok = 0; 85 for(int i = cur[u]; ~i; i = e[i].nex){ 86 int v = e[i].v; 87 if(d[u] == d[v]+1 && e[i].cap > e[i].flow){ 88 p[v] = i; 89 ok = 1; 90 cur[u] = i; 91 u = v; 92 break; 93 } 94 } 95 if(!ok){ 96 int m = N-1; 97 for(int i = head[u]; ~i; i = e[i].nex){ 98 if(e[i].cap > e[i].flow && ~d[e[i].v]) m = min(m, d[e[i].v]); 99 } 100 if(--num[d[u]] == 0) break; 101 num[d[u]=m+1]++; 102 cur[u] = head[u]; 103 if(u != S) u = e[p[u]].u; 104 } 105 } 106 return flow; 107 } 108 109 int main(){ 110 init(); 111 int n, m; 112 scanf("%d %d", &n, &m); 113 int u, v; 114 for(int i = 0; i < m; i++){ 115 scanf("%d %d", &u, &v); 116 add(2*u-1, 2*v, 1); 117 } 118 S = 0; 119 T = 2*n+1; 120 N = T+1; 121 for(int i = 1; i <= n; i++){ 122 add(S, 2*i-1, 1); 123 add(2*i, T, 1); 124 } 125 int ans = ISAP(); 126 printf("%d\n", n-ans); 127 }
以上是关于网络流四·最小路径覆盖 HihoCoder - 1394的主要内容,如果未能解决你的问题,请参考以下文章