1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| #include <stdio.h> #include <string.h> #include <queue> using namespace std; #define il inline
template <typename T> il T abs(T x) { return x > 0 ? x : -x; }
const int N = 110, M = N * N << 1, INF = 0x3f3f3f3f;
struct coor { int x, y, z; } a[N], b[N]; struct node { int u, v, w, f, next; } e[M]; int h[N << 1], tot = 0;
bool vis[N << 1]; int n, m, s, t; int cnt[N << 1], pre[N << 1]; il void add(int u, int v, int w, int f) { e[tot] = (node) {u, v, w, f, h[u]}; h[u] = tot++; }
int bp[N][N], dis[N << 1], p[N][N], occ[N];
deque<int> q; bool cyc[N << 1];
il void check(int v) { do { cyc[v] = true; v = e[pre[v]].u; } while(!cyc[v]); int u = v; do { --e[pre[v]].w; ++e[pre[v]^1].w; v = e[pre[v]].u; } while(u != v); for(int i=1; i<=m; ++i) for(int j = h[n+i]; j != -1; j = e[j].next) if(e[j].v != t) bp[e[j].v][i] = e[j].w; printf("SUBOPTIMAL\n"); for(int i=1; i<=n; ++i) { for(int j=1; j<=m; ++j) printf("%d ", bp[i][j]); printf("\n"); } } int main() { scanf("%d%d", &n, &m); for(int i=1; i<=n; ++i) scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z); for(int i=1; i<=m; ++i) scanf("%d%d%d", &b[i].x, &b[i].y, &b[i].z); for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) scanf("%d", &p[i][j]), occ[j] += p[i][j]; memset(h, -1, sizeof h); s = 0, t = n+m+1; for(int i=1; i<=n; ++i) { add(s, i, a[i].z, 0); add(i, s, 0, 0); } for(int i=1; i<=n; ++i) { for(int j=1; j<=m; ++j) { int f = abs(a[i].x - b[j].x) + abs(a[i].y - b[j].y) + 1; add(i, n+j, INF, f); add(n+j, i, p[i][j], -f); } } for(int i=1; i<=m; ++i) { add(n+i, t, b[i].z - occ[i], 0); add(t, n+i, occ[i], 0); } memset(dis, 0x3f, sizeof dis); q.push_front(s); vis[s] = true; ++cnt[s]; dis[s] = 0; while(!q.empty()) { int u = q.front(); q.pop_front(); vis[u] = false; for(int i = h[u]; i != -1; i = e[i].next) { int v = e[i].v; if(e[i].w and dis[v] > dis[u] + e[i].f) { pre[v] = i; dis[v] = dis[u] + e[i].f; if(!vis[v]) { if(!q.empty() and dis[v] >= dis[q.front()]) q.push_back(v); else q.push_front(v); vis[v] = true; ++cnt[v]; if(cnt[v] == t+1) { check(v); return 0; } } } } } printf("OPTIMAL\n"); return 0; }
|