就是一个网络流。red结点容量为2,查看最大流量是否大于等于2。对于条件2,把边反向加入建图。条件1,边正向加入建图。
1 /* 4183 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 typedef struct { 43 int u, v, c, f; 44 } Edge_t; 45 46 const int maxn = 605; 47 Edge_t E[maxn*maxn]; 48 vi vc[maxn]; 49 double F[maxn]; 50 int X[maxn], Y[maxn], R[maxn]; 51 int pre[maxn], a[maxn], ID[maxn]; 52 int n, m; 53 54 void addEdge(int u, int v, int c) { 55 E[m].u = u; 56 E[m].v = v; 57 E[m].c = c; 58 E[m].f = 0; 59 60 E[m+1].u = v; 61 E[m+1].v = u; 62 E[m+1].c = 0; 63 E[m+1].f = 0; 64 65 vc[u].pb(m); 66 vc[v].pb(m+1); 67 68 m += 2; 69 } 70 71 bool judge(int i, int j) { 72 if (F[i] >= F[j]) 73 return false; 74 if ((R[i]+R[j])*(R[i]+R[j]) > (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j])) 75 return true; 76 return false; 77 } 78 79 bool bfs(int s, int t) { 80 int u, v; 81 int sz, k; 82 queue<int> Q; 83 84 memset(a, 0, sizeof(a)); 85 Q.push(s); 86 a[s] = INT_MAX; 87 pre[s] = s; 88 89 while (!Q.empty()) { 90 u = Q.front(); 91 Q.pop(); 92 sz = SZ(vc[u]); 93 rep(i, 0, sz) { 94 k = vc[u][i]; 95 v = E[k].v; 96 if (!a[v] && E[k].f<E[k].c) { 97 a[v] = min(a[u], E[k].c-E[k].f); 98 pre[v] = u; 99 ID[v] = k; 100 Q.push(v); 101 } 102 } 103 } 104 105 return a[t]==0; 106 } 107 108 int EK(int s, int t) { 109 int ret = 0, tmp; 110 int u, v, k; 111 112 while (1) { 113 if (bfs(s, t)) 114 break; 115 116 tmp = a[t]; 117 for (v=t,u=pre[v]; v!=s; v=u,u=pre[v]) { 118 k = ID[v]; 119 E[k].f += tmp; 120 E[k^1].f -= tmp; 121 } 122 ret += tmp; 123 } 124 125 return ret; 126 } 127 128 int main() { 129 ios::sync_with_stdio(false); 130 #ifndef ONLINE_JUDGE 131 freopen("data.in", "r", stdin); 132 freopen("data.out", "w", stdout); 133 #endif 134 135 int case_n, n_; 136 int s, t; 137 int ans; 138 139 scanf("%d", &case_n); 140 while (case_n--) { 141 scanf("%d", &n_); 142 n = n_ + n_; 143 m = 0; 144 145 rep(i, 0, n) 146 vc[i].clr(); 147 148 rep(i, 0, n_) { 149 scanf("%lf %d %d %d", &F[i], &X[i], &Y[i], &R[i]); 150 if (F[i] == 400.0) 151 s = i; 152 else if (F[i] == 789.0) 153 t = i; 154 } 155 156 if (judge(s, t)) { 157 puts("Game is VALID"); 158 continue; 159 } 160 161 rep(i, 0, n_) { 162 if (i!=s && i!=t) 163 addEdge(i<<1, i<<1|1, 1); 164 rep(j, 0, i) { 165 if (judge(i, j)) 166 addEdge(i<<1|1, j<<1, 1); 167 else if (judge(j, i)) 168 addEdge(j<<1|1, i<<1, 1); 169 } 170 } 171 172 addEdge(s<<1, s<<1|1, 2); 173 174 ans = EK(s<<1, t<<1); 175 176 if (ans >= 2) 177 puts("Game is VALID"); 178 else 179 puts("Game is NOT VALID"); 180 } 181 182 #ifndef ONLINE_JUDGE 183 printf("time = %d. ", (int)clock()); 184 #endif 185 186 return 0; 187 }