1 #include <iostream> 2 #include <cstdio> 3 #include <fstream> 4 #include <algorithm> 5 #include <cmath> 6 #include <deque> 7 #include <vector> 8 #include <queue> 9 #include <string> 10 #include <cstring> 11 #include <map> 12 #include <stack> 13 #include <set> 14 #define INF 0x3f3f3f3f 15 #define OPEN_FILE 16 #define MAXN 626 17 using namespace std; 18 19 int n; 20 int win[MAXN], remain[MAXN][MAXN]; 21 struct Edge{ 22 int from, to, cap, flow; 23 //Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){}; 24 }; 25 bool comp(const Edge& a, const Edge& b){ 26 return (a.from < b.from || (a.from == b.from && a.to < b.to)); 27 } 28 struct Dinic{ 29 int n, m, i, s, t; 30 Edge e; 31 vector<Edge> edges; 32 vector<int> G[MAXN]; 33 int d[MAXN], cur[MAXN]; 34 bool vis[MAXN]; 35 void init(int n){ 36 this->n = n; 37 for (i = 0; i <= n; i++){ 38 G[i].clear(); 39 } 40 edges.clear(); 41 } 42 void AddEdge(int from, int to, int cap){ 43 edges.push_back(Edge{ from, to, cap, 0 }); 44 edges.push_back(Edge{ to, from, 0, 0 }); 45 m = edges.size(); 46 G[from].push_back(m - 2); 47 G[to].push_back(m - 1); 48 } 49 bool BFS(){ 50 memset(vis, 0, sizeof(vis)); 51 queue<int> Q; 52 Q.push(s); 53 d[s] = 0; 54 vis[s] = 1; 55 while (!Q.empty()){ 56 int x = Q.front(); 57 Q.pop(); 58 for (i = 0; i < G[x].size(); i++){ 59 Edge& e = edges[G[x][i]]; 60 if (!vis[e.to] && e.cap > e.flow){ 61 vis[e.to] = true; 62 d[e.to] = d[x] + 1; 63 Q.push(e.to); 64 } 65 } 66 } 67 return vis[t]; 68 } 69 int DFS(int x, int a){ 70 if (x == t || a == 0) return a; 71 int flow = 0, f; 72 for (int& i = cur[x]; i < G[x].size(); i++){ 73 Edge& e = edges[G[x][i]]; 74 if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0){ 75 e.flow += f; 76 edges[G[x][i] ^ 1].flow -= f; 77 flow += f; 78 a -= f; 79 if (a == 0) break; 80 } 81 } 82 return flow; 83 } 84 int MaxFlow(int s, int t, int need){ 85 int flow = 0; 86 this->s = s; 87 this->t = t; 88 while (BFS()){ 89 memset(cur, 0, sizeof(cur)); 90 flow += DFS(s, INF); 91 if (flow > need) return flow; 92 } 93 return flow; 94 } 95 bool checkFull(int s){ 96 for (int i = 0; i < G[s].size(); i++){ 97 if (edges[G[s][i]].flow != edges[G[s][i]].cap){ 98 return false; 99 } 100 } 101 return true; 102 } 103 }; 104 105 int main() 106 { 107 #ifdef OPEN_FILE 108 freopen("in.txt", "r", stdin); 109 freopen("out.txt", "w", stdout); 110 #endif // OPEN_FILE 111 int T, x; 112 scanf("%d", &T); 113 for (int cas = 1; cas <= T; cas++){ 114 scanf("%d", &n); 115 memset(win, 0, sizeof(win)); 116 for (int i = 1; i <= n; i++){ 117 scanf("%d%d", &win[i], &x); 118 } 119 memset(remain, 0, sizeof(remain)); 120 int p = 0; 121 for (int i = 1; i <= n; i++){ 122 for (int j = 1; j <= n; j++){ 123 scanf("%d", &x); 124 if (i == j) continue; 125 remain[i][0] += x; 126 if (remain[i][j] == 0 && remain[j][i] == 0){ 127 remain[i][j] = x; 128 ++p; 129 } 130 } 131 } 132 int s = 0, t = n + p + 1, q; 133 bool flag, first; 134 Dinic ex; 135 first = false; 136 for (int k = 1; k <= n; k++){ 137 ex.init(n * n); 138 flag = false; 139 q = 1; 140 int total = win[k] + remain[k][0]; 141 for (int i = 1; i <= n; i++){ 142 for (int j = i + 1; j <= n; j++){ 143 if (!remain[i][j]) continue; 144 ex.AddEdge(s, q, remain[i][j]); 145 ex.AddEdge(q, p + i, INF); 146 ex.AddEdge(q, p + j, INF); 147 q++; 148 } 149 if (total - win[i] < 0) { 150 flag = true; 151 break; 152 } 153 ex.AddEdge(p + i, t, total - win[i]); 154 } 155 if (flag){ 156 continue; 157 } 158 ex.MaxFlow(s, t, INF); 159 if (ex.checkFull(0)){ 160 if (first){ 161 printf(" "); 162 } 163 printf("%d", k); 164 first = true; 165 } 166 } 167 printf(" "); 168 } 169 }