/***********************************************
最大流算法(dinic)
在深搜时,刚开始没有把d[cur] = -1超时,改之后就好了
相当于一个剪枝操作
***********************************************/
#include <iostream>
#include <queue>
#include <cstring>
#include <fstream>
#include <cstdio>
using namespace std;
const int MAXD = 7200;
const int MAXM = 36000;
const int INF = 1000000000;
int first[MAXD], next[MAXM], u[MAXM], v[MAXM], flow[MAXM];
int d[MAXD];
int s, a, b;
int e;
void init();
void add(int x, int y, int f);
int bfs();
int dfs(int cur, int f);
int dinic();
int main(int argc, char *argv[])
{
int t;
#ifndef ONLINE_JUDGE
freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%d", &t);
while (t--) {
init();
int ans = dinic();
if (ans)
printf("possible\n");
else
printf("not possible\n");
}
return 0;
}
void init()
{
e = 0;
//cin >> s >> a >> b;
scanf("%d%d%d", &s, &a, &b);
memset(first, -1, sizeof(first));
memset(flow, 0, sizeof(flow));
for (int i = 1; i <= a; i++) {
int z = a + i;
add(2 * z ^ 1, 1, 1);
add(1, 2 * z ^ 1, 0);
}
for (int i = 1; i <= s; i++) {
int z = i * a + 1;
add(2 * z ^ 1, 1, 1);
add(1, 2 * z ^ 1, 0);
}
for (int i = 1; i <= a; i++) {
int z = s * a + i;
add(2 * z ^ 1, 1, 1);
add(1, 2 * z ^ 1, 0);
}
for (int i = 1; i <= s; i++) {
int z = i * a + a;
add(2 * z ^ 1, 1, 1);
add(1, 2 * z ^ 1, 0);
}
for (int i = 1; i <= s; i++) {
for (int j = 1; j <= a; j++) {
int z = i * a + j;
add(2 * z, 2 * z ^ 1, 1);
add(2 * z ^ 1, 2 * z, 0);
if (i + 1 <= s) {
int newz = (i + 1) * a + j;
add(2 * z ^ 1, 2 * newz, 1);
add(2 * newz, 2 * z ^ 1, 0);
add(2 * newz ^ 1, 2 * z, 1);
add(2 * z, 2 * newz ^ 1, 0);
}
if (j + 1 <= a) {
int newz = i * a + j + 1;
add(2 * z ^ 1, 2 * newz, 1);
add(2 * newz, 2 * z ^ 1, 0);
add(2 * newz ^ 1, 2 * z, 1);
add(2 * z, 2 * newz ^ 1, 0);
}
}
}
for (int i = 0; i < b; i++) {
int x, y, z;
scanf("%d%d", &x, &y);
z = x * a + y;
add(0, 2 * z, 1);
add(2 * z, 0, 0);
}
}
void add(int x, int y, int f)
{
u[e] = x;
v[e] = y;
flow[e] = f;
next[e] = first[x];
first[x] = e;
e++;
}
int bfs()
{
queue<int> q;
memset(d, -1, sizeof(d));
q.push(0);
d[0] = 0;
while (!q.empty()) {
int u1 = q.front();
q.pop();
for (int j = first[u1]; j != -1; j = next[j]) {
if (flow[j] > 0 && d[v[j]] == -1) {
d[v[j]] = d[u1] + 1;
if (v[j] == 1)
return 1;
q.push(v[j]);
}
}
}
return 0;
}
int dfs(int cur, int f)
{
if (cur == 1 || f == 0)
return f;
int ans = 0;
for (int j = first[cur]; j != -1; j = next[j]) {
if (flow[j] > 0 && d[v[j]] == d[cur] + 1) {
int t = dfs(v[j], flow[j] < f ? flow[j]:f);
flow[j] -= t;
flow[j ^ 1] += t;
f -= t;
ans += t;
if (f == 0) break;
}
}
d[cur] = -1;
return ans;
}
int dinic()
{
int ans = 0;
while (bfs()) {
ans += dfs(0, INF);
}
if (ans == b)
return 1;
else return 0;
}
UVa563 - Crimewave
最新推荐文章于 2017-02-12 14:41:43 发布