这个道题,第一次邻接表写的,wa了,然后换的矩阵,结果还是不对,但是发现哪里错了
主要是建图,判断两个点是不是起点或者汇点,对这两个点,就不要拆了,因为没有费用
其余的所有的点,都用拆成两个点,然后容量为这个computer的费用,其他的就按照规则,从原始点进,从拆出的点出
矩阵的代码如下:
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int N = 100; const int INF = 100000000; int n, m; int cap[N][N], flow[N][N]; int p[N], a[N]; int maxflow() { queue<int> q; memset(flow, 0, sizeof(flow)); int f = 0; while ( 1 ) { memset(a, 0, sizeof(a)); a[1] = INF; q.push(1); while ( !q.empty() ) { int u = q.front(); q.pop(); for ( int v = 1; v <= n + n - 1; v++ ) if ( !a[v] && cap[u][v] > flow[u][v] ) { p[v] = u; a[v] = min( a[u], cap[u][v] - flow[u][v] ); q.push(v); } } if ( a[n] == 0 ) break; for ( int u = n; u != 1; u = p[u] ) { //printf("%d ", u ); flow[p[u]][u] += a[n]; flow[u][p[u]] -= a[n]; } f += a[n]; } return f; } int main() { while ( scanf("%d%d", &n, &m) != EOF && !( !n && !m ) ) { memset( cap, 0, sizeof(cap) ); for ( int i = 2; i < n; ++i ) { int com, c; scanf("%d%d", &com, &c); cap[com][com+n] = cap[com+n][com] = c; } for ( int i = 0; i < m; ++i ) { int u, v, c; scanf("%d%d%d", &u, &v, &c); if ( u == 1 && v != n ) cap[u][v] = cap[v+n][u] = c; else if ( u == 1 && v == n ) cap[u][v] = cap[v][u] = c; else if ( u == n && v != 1 ) cap[v+n][u] = cap[u][v] = c; else if ( u == n && v == 1 ) cap[u][v] = cap[v][u] = c; else cap[u+n][v] = cap[v+n][u] = c; } /*for ( int i = 1; i < 2*n; ++i ) { for ( int j = 1; j < 2*n; ++j ) printf("%d ", cap[i][j]); printf("\n"); }*/ int ans = maxflow(); printf("%d\n", ans); } }
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int N = 150; const int M = 4500; const int INF = 100000000; struct edge { int v, next, cap, flow; }e[M]; int n, m, id; int head[N]; int maxflow() { int f = 0, a[N], p[N], r[N]; while ( 1 ) { queue <int> q; int s = 1, t = n, np = n + n - 1; q.push(s); memset( a, 0, sizeof(a) ); a[s] = INF; while ( !q.empty() ) { int u = q.front(); q.pop(); for ( int i = head[u]; i != -1; i = e[i].next ) { int v = e[i].v, cap = e[i].cap, flow = e[i].flow; if ( cap > flow && !a[v] ) { a[v] = min( a[u], cap - flow ); p[v] = u; r[v] = i; q.push(v); } } } if ( a[t] == 0 ) break; for ( int u = t; u != s; u = p[u] ) { int ei = r[u]; e[ei].flow += a[t]; e[ei^1].flow -= a[t]; } f += a[t]; } return f; } void add( int u, int v, int c ) { e[id].next = head[u]; e[id].v = v, e[id].cap = c, e[id].flow = 0; head[u] = id++; e[id].next = head[v]; e[id].v = u, e[id].cap = 0, e[id].flow = 0; head[v] = id++; } int main() { while ( scanf("%d%d", &n, &m) != EOF && !(!n && !m) ) { id = 0; for ( int i = 0; i <= 2*n; ++i ) head[i] = -1; for ( int i = 2, node, cost; i < n; ++i ) { scanf("%d%d", &node, &cost); add( node, node + n, cost ); add( node + n, node, cost ); } for ( int i = 0; i < m; ++i ) { int u, v, c; scanf("%d%d%d", &u, &v, &c); if ( u == 1 && v == n ) add( u, v, c ), add( v, u, c ); else if ( u == 1 && v != n ) add( u, v, c ), add( v+n, u, c ) ; else if ( v == 1 && u == n ) add( v, u, c ), add( u, v, c ); else add( v + n, u, c ), add( u+n, v, c ); } printf("%d\n", maxflow() ); } }