收获:
1、流量为0的边可以不加入。
2、最小割方案要与决策方案对应。
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <vector> 5 #define min(a,b) ((a)<(b)?(a):(b)) 6 #define oo 0x3f3f3f3f 7 #define N 610 8 using namespace std; 9 10 typedef long long dnt; 11 struct Edge { 12 int u, v, f; 13 Edge( int u, int v, int f ):u(u),v(v),f(f){} 14 }; 15 struct Dinic { 16 int src, dst; 17 vector<Edge> edge; 18 vector<int> g[N]; 19 int dep[N], cur[N], qu[N], bg, ed; 20 void init( int src, int dst ) { 21 this->src = src; 22 this->dst = dst; 23 } 24 void adde( int u, int v, int f ) { 25 g[u].push_back( edge.size() ); 26 edge.push_back( Edge(u,v,f) ); 27 g[v].push_back( edge.size() ); 28 edge.push_back( Edge(v,u,0) ); 29 } 30 bool bfs() { 31 memset( dep, 0, sizeof(dep) ); 32 qu[bg=ed=1] = src; 33 dep[src] = 1; 34 while( bg<=ed ) { 35 int u=qu[bg++]; 36 for( int t=0; t<g[u].size(); t++ ) { 37 Edge &e = edge[g[u][t]]; 38 if( e.f && !dep[e.v] ) { 39 dep[e.v] = dep[e.u] + 1; 40 qu[++ed] = e.v; 41 } 42 } 43 } 44 return dep[dst]; 45 } 46 int dfs( int u, int a ) { 47 if( u==dst || a==0 ) return a; 48 int remain=a, past=0, na; 49 for( int &t=cur[u]; t<g[u].size(); t++ ) { 50 Edge &e=edge[g[u][t]]; 51 Edge &ve=edge[g[u][t]^1]; 52 if( e.f && dep[e.v]==dep[e.u]+1 && (na=dfs(e.v,min(remain,e.f))) ) { 53 remain -= na; 54 past += na; 55 e.f -= na; 56 ve.f += na; 57 if( !remain ) break; 58 } 59 } 60 return past; 61 } 62 int maxflow() { 63 int rt=0; 64 while( bfs() ) { 65 memset( cur, 0, sizeof(cur) ); 66 rt += dfs(src,oo); 67 } 68 return rt; 69 } 70 }D; 71 72 int n, m; 73 int src, dst; 74 75 int main() { 76 scanf( "%d%d", &n, &m ); 77 D.init( src=0, dst=n+1 ); 78 for( int i=1,v; i<=n; i++ ) { 79 scanf( "%d", &v ); 80 if( !v ) D.adde( src, i, 1 ); 81 else D.adde( i, dst, 1 ); 82 } 83 for( int i=1; i<=m; i++ ) { 84 int u, v; 85 scanf( "%d%d", &u, &v ); 86 D.adde( u, v, 1 ); 87 D.adde( v, u, 1 ); 88 } 89 printf( "%d\n", D.maxflow() ); 90 }