/// {{{ Author: Wang, Yen-Jen // include #pragma GCC optimize("Ofast") #include // using using namespace std; // types typedef long long ll; typedef pair pii; // macro #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin() , (x).end() #define REP(i , n) for(int i = 0; i < int(n); i++) #define REP1(i , a , b) for(int i = a; i <= int(b); i++) #define F first #define S second #define MP make_pair #define PB push_back #define LC o<<1 , l , m #define RC o<<1|1 , m + 1 , r #define MS(x , v) memset(x , (v) , sizeof(x)) // input inline bool SR(int &x) { return scanf("%d",&x) == 1; } inline bool SR(ll &x) { return scanf("%lld",&x) == 1; } inline bool SR(double &x) { return scanf("%lf",&x) == 1; } inline bool SR(char *s) { return scanf("%s",s) == 1; } inline bool RI() { return true; } template inline bool RI(I &x , T&... tail) { return SR(x) && RI(tail...); } // output inline void SP(const int x) { printf("%d",x); } inline void SP(const ll x) { printf("%lld",x); } inline void SP(const double x) { printf("%.16lf",x); } inline void SP(const char *s) { printf("%s",s); } inline void PL() { puts(""); } template inline void PL(const I x , const T... tail) { SP(x); if(sizeof...(tail)) putchar(' '); PL(tail...); } // debug #define WangYenJen #ifdef WangYenJen template void _DOING(const char *s , I&& x) { cerr << s << " = " << x << endl; } template void _DOING(const char *s , I&& x , T&&... tail) { int c = 0; while(*s != ',' || c != 0) { if(*s == '(' || *s == '[' || *s == '{') c++; if(*s == ')' || *s == ']' || *s == '}') c--; cerr << *s++; } cerr << " = " << x << " , "; _DOING(s + 1 , tail...); } #define DEBUG(...) \ do {\ fprintf(stderr , "%s: Line %d - ",__PRETTY_FUNCTION__,__LINE__);\ _DOING(#__VA_ARGS__ , __VA_ARGS__);\ } while(0); #else #define DEBUG(...) #endif // constant number const int INF = 0x3f3f3f3f; const ll INF64 = 0x3f3f3f3f3f3f3f3fll; // random function inline int RAND() { static int x = 880301; return (x = x * 0xdefaced + 1) % 0x7fffffff; } /// }}} const int MAX_N = 400 + 7; int nl , nr; int pre[MAX_N]; ll slack[MAX_N]; ll W[MAX_N][MAX_N]; ll lx[MAX_N] , ly[MAX_N]; int mx[MAX_N] , my[MAX_N]; bool vx[MAX_N] , vy[MAX_N]; void augment(int u) { if(!u) return; augment(mx[pre[u]]); mx[pre[u]] = u; my[u] = pre[u]; } inline void match(int x) { queue que; que.push(x); while(1) { while(!que.empty()) { x = que.front(); que.pop(); vx[x] = 1; REP1(y , 1 , nr) { if(vy[y]) continue; ll t = lx[x] + ly[y] - W[x][y]; if(t > 0) { if(slack[y] >= t) slack[y] = t , pre[y] = x; continue; } pre[y] = x; if(!my[y]) { augment(y); return; } vy[y] = 1; que.push(my[y]); } } ll t = INF64; REP1(y , 1 , nr) if(!vy[y]) t = min(t , slack[y]); REP1(x , 1 , nl) if(vx[x]) lx[x] -= t; REP1(y , 1 , nr) { if(vy[y]) ly[y] += t; else slack[y] -= t; } REP1(y , 1 , nr) { if(vy[y] || slack[y]) continue; if(!my[y]) { augment(y); return; } vy[y] = 1; que.push(my[y]); } } } int main() { int T; RI(T); int kcase = 0; while (T--) { int n; RI(n); nl = nr = n; MS(mx, 0); MS(my, 0); REP1(i, 1, n) { lx[i] = -INF64; ly[i] = 0; } REP1(i, 1, n) { REP1(j, 1, n) { RI(W[i][j]); W[i][j] *= -1; lx[i] = max(lx[i], W[i][j]); } } REP1(i , 1 , nl) { REP1(x , 1 , nl) vx[x] = 0; REP1(y , 1 , nr) vy[y] = 0 , slack[y] = INF64; match(i); } ll ans = 0; REP1(i, 1, n) ans += lx[i] + ly[i]; ans *= -1; printf("Case #%d: %lld\n", ++kcase, ans); } return 0; }