#include #include #include #include #include #include #include using namespace std; struct Pair { int x; int y; Pair() {}; Pair(int _x, int _y) : x(_x), y(_y) {}; bool operator == (const Pair & rht) { return x == rht.x && y == rht.y; } }; struct Stream { int idx; Pair from; Pair to; Stream() {}; Stream(int _idx, const Pair & _from, const Pair & _to) : idx(_idx), from(_from), to(_to) {}; }; int dist(const Stream & str) { int dx = (str.from.x - str.to.x); int dy = (str.from.y - str.to.y); return dx*dx + dy*dy; } int computed[250]; bool comp(const Stream & lht, const Stream & rht) { int f1,f2; if (computed[lht.idx] == 0) { computed[lht.idx] = dist(lht); } if (computed[rht.idx] == 0) { computed[rht.idx] == dist(rht); } f1 = computed[lht.idx]; f2 = computed[rht.idx]; return f1 < f2; } FILE *in, *out; int n,p,b; Stream possib[250]; int g[100][100]; int must[100][100]; char gen[100][100]; char used[100][100][250]; char used2[100][100][250]; Pair path[100][100][250]; vector answer[250]; vector real[250]; void prepare() { in = fopen("flow.in", "r"); out = fopen("flow.out", "w"); fscanf(in, "%d%d", &n, &p); for (int i = 0; i < p; ++i) { int f1,f2,f3,f4; fscanf(in, "%d%d%d%d", &f1,&f2,&f3,&f4); possib[i] = Stream(i, Pair(f1,f2), Pair(f3,f4)); answer[i].reserve(n*n); real[i].reserve(n*n); must[f1][f2] = i+1; must[f3][f4] = i+1; } fscanf(in, "%d", &b); for (int i = 0; i < b; ++i) { int f1,f2; fscanf(in, "%d%d", &f1,&f2); gen[f1][f2] = 1; } srand(time(NULL)); //sort(possib, possib+p, comp); } inline void finish() { fclose(in); fclose(out); } inline bool ok(int x, int y) { return (x >= 0 && y >=0 && x < n && y < n && g[x][y]==0); } void dfs(int idx, Pair U, Pair prev) { Pair delta[] = { Pair(-1,0), Pair(1,0), Pair(0, -1), Pair(0, 1) }; random_shuffle(delta,delta+4); if (used2[U.x][U.y][idx]) return; if (!ok(U.x,U.y)) return; if (!(must[U.x][U.y] == idx+1 || must[U.x][U.y] == 0)) return; if (gen[U.x][U.y]) return; path[U.x][U.y][idx] = prev; used2[U.x][U.y][idx] = 1; if (U == possib[idx].to) { return; } for (int i = 0; i < 4; ++i) { int nx = delta[i].x + U.x; int ny = delta[i].y + U.y; dfs(idx, Pair(nx,ny), U); } } bool hasPath(const Stream & str) { static int dx[] = {-1,1,0,0}; static int dy[] = {0,0,-1,1}; queue q; used[str.from.x][str.from.y][str.idx] = 1; q.push(str.from); while (!q.empty()) { const Pair & tp = q.front(); q.pop(); for (int i = 0; i < 4; ++i) { int nx = dx[i] + tp.x; int ny = dy[i] + tp.y; if (ok(nx,ny) && !used[nx][ny][str.idx] && (must[nx][ny] == str.idx+1 || must[nx][ny] == 0) && gen[nx][ny]==0) { Pair nPair = Pair(nx,ny); used[nx][ny][str.idx] = 1; //path[nx][ny][str.idx] = tp; if (nPair == str.to) return true; q.push(nPair); } } } return false; } void save(const Stream & str) { Pair cur = str.to; while(!(cur == str.from)) { answer[str.idx].push_back(cur); gen[cur.x][cur.y] = 1; cur = path[cur.x][cur.y][str.idx]; } gen[cur.x][cur.y] = 1; answer[str.idx].push_back(cur); } int eval() { int blocks=0, seqs=0; for (int i = 0; i < p; ++i) { int sz = answer[i].size(); if (sz != 0) { blocks += sz; seqs+=1; } } return blocks*seqs; } void update() { for (int i = 0; i < p; ++i) { real[i] = answer[i]; answer[i].clear(); } } void start() { int score = 0; double elapsed = 0.0; while (true) { if (elapsed > 4.0) break; random_shuffle (possib, possib+p); clock_t beg = clock(); for (int i = 0; i < p; ++i) { if (hasPath(possib[i])) { dfs(possib[i].idx, possib[i].from, Pair(-1,-1)); save(possib[i]); } } int tmp = eval(); if ( tmp > score) update(); clock_t end = clock(); double elapsed_secs = double(end - beg) / CLOCKS_PER_SEC; elapsed += elapsed_secs; } } void output() { for (int i = 0; i < p; ++i) { int sz = real[i].size(); fprintf(out, "%d", sz); for (int j = 0; j < sz; ++j) { fprintf(out, " %d %d", real[i][j].x, real[i][j].y); } fprintf(out,"\n"); } } int main() { prepare(); start(); output(); finish(); return 0; }