将一个无向图分成许多回路,回路点交集为空,点幷集为V。幷最小化回路边权和。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <vector> 5 #define maxn 2010 6 #define oo 0x3f3f3f3f 7 using namespace std; 8 9 struct Edge { 10 int u, v, c, f; 11 Edge( int u, int v, int c, int f ):u(u),v(v),c(c),f(f){} 12 }; 13 struct Mcmf { 14 int n, src, dst; 15 vector<Edge> edge; 16 vector<int> g[maxn]; 17 int dis[maxn], pth[maxn], ext[maxn]; 18 19 void init( int n, int src, int dst ) { 20 this->n = n; 21 this->src = src; 22 this->dst = dst; 23 for( int u=1; u<=n; u++ ) 24 g[u].clear(); 25 edge.clear(); 26 } 27 void add_edge( int u, int v, int c, int f ) { 28 g[u].push_back( edge.size() ); 29 edge.push_back( Edge(u,v,c,f) ); 30 g[v].push_back( edge.size() ); 31 edge.push_back( Edge(v,u,-c,0) ); 32 } 33 bool spfa( int &flow, int &cost ) { 34 queue<int> qu; 35 memset( dis, 0x3f, sizeof(dis) ); 36 qu.push( src ); 37 dis[src] = 0; 38 pth[src] = -1; 39 ext[src] = true; 40 while( !qu.empty() ) { 41 int u=qu.front(); 42 qu.pop(); 43 ext[u] = false; 44 for( int t=0; t<g[u].size(); t++ ) { 45 Edge &e = edge[g[u][t]]; 46 if( e.f && dis[e.v]>dis[e.u]+e.c ) { 47 dis[e.v] = dis[e.u]+e.c; 48 pth[e.v] = g[u][t]; 49 if( !ext[e.v] ) { 50 ext[e.v] = true; 51 qu.push( e.v ); 52 } 53 } 54 } 55 } 56 if( dis[dst]==oo ) return false; 57 int flw = oo; 58 for( int eid=pth[dst]; eid!=-1; eid=pth[edge[eid].u] ) 59 flw = min( flw, edge[eid].f ); 60 for( int eid=pth[dst]; eid!=-1; eid=pth[edge[eid].u] ) { 61 edge[eid].f -= flw; 62 edge[eid^1].f += flw; 63 } 64 flow += flw; 65 cost += flw*dis[dst]; 66 return true; 67 } 68 bool mcmf( int &flow, int &cost ) { 69 flow = cost = 0; 70 while(spfa(flow,cost)); 71 return true; 72 } 73 }; 74 75 int n, m; 76 Mcmf M; 77 78 int main() { 79 int T; 80 scanf( "%d", &T ); 81 for( int cas=1; cas<=T; cas++ ) { 82 printf( "Case %d: ", cas ); 83 scanf( "%d%d", &n, &m ); 84 M.init( n+n+2, n+n+1, n+n+2 ); 85 for( int i=1,u,v,w; i<=m; i++ ) { 86 scanf( "%d%d%d", &u, &v, &w ); 87 M.add_edge( u, v+n, w, 1 ); 88 M.add_edge( v, u+n, w, 1 ); 89 } 90 for( int u=1; u<=n; u++ ) { 91 M.add_edge( M.src, u, 0, 1 ); 92 M.add_edge( u+n, M.dst, 0, 1 ); 93 } 94 int flow, cost; 95 M.mcmf( flow, cost ); 96 if( flow!=n ) printf( "NO\n" ); 97 else printf( "%d\n", cost ); 98 } 99 }
时间: 2024-10-29 16:46:46