您的位置:首页 > 其它

【HDOJ】4183 Pahom on Water

2015-10-09 23:34 316 查看
就是一个网络流。red结点容量为2,查看最大流量是否大于等于2。对于条件2,把边反向加入建图。条件1,边正向加入建图。

/* 4183 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000")

#define sti                set<int>
#define stpii            set<pair<int, int> >
#define mpii            map<int,int>
#define vi                vector<int>
#define pii                pair<int,int>
#define vpii            vector<pair<int,int> >
#define rep(i, a, n)     for (int i=a;i<n;++i)
#define per(i, a, n)     for (int i=n-1;i>=a;--i)
#define clr                clear
#define pb                 push_back
#define mp                 make_pair
#define fir                first
#define sec                second
#define all(x)             (x).begin(),(x).end()
#define SZ(x)             ((int)(x).size())
#define lson            l, mid, rt<<1
#define rson            mid+1, r, rt<<1|1

typedef struct {
int u, v, c, f;
} Edge_t;

const int maxn = 605;
Edge_t E[maxn*maxn];
vi vc[maxn];
double F[maxn];
int X[maxn], Y[maxn], R[maxn];
int pre[maxn], a[maxn], ID[maxn];
int n, m;

void addEdge(int u, int v, int c) {
E[m].u = u;
E[m].v = v;
E[m].c = c;
E[m].f = 0;

E[m+1].u = v;
E[m+1].v = u;
E[m+1].c = 0;
E[m+1].f = 0;

vc[u].pb(m);
vc[v].pb(m+1);

m += 2;
}

bool judge(int i, int j) {
if (F[i] >= F[j])
return false;
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]))
return true;
return false;
}

bool bfs(int s, int t) {
int u, v;
int sz, k;
queue<int> Q;

memset(a, 0, sizeof(a));
Q.push(s);
a[s] = INT_MAX;
pre[s] = s;

while (!Q.empty()) {
u = Q.front();
Q.pop();
sz = SZ(vc[u]);
rep(i, 0, sz) {
k = vc[u][i];
v = E[k].v;
if (!a[v] && E[k].f<E[k].c) {
a[v] = min(a[u], E[k].c-E[k].f);
pre[v] = u;
ID[v] = k;
Q.push(v);
}
}
}

return a[t]==0;
}

int EK(int s, int t) {
int ret = 0, tmp;
int u, v, k;

while (1) {
if (bfs(s, t))
break;

tmp = a[t];
for (v=t,u=pre[v]; v!=s; v=u,u=pre[v]) {
k = ID[v];
E[k].f += tmp;
E[k^1].f -= tmp;
}
ret += tmp;
}

return ret;
}

int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

int case_n, n_;
int s, t;
int ans;

scanf("%d", &case_n);
while (case_n--) {
scanf("%d", &n_);
n = n_ + n_;
m = 0;

rep(i, 0, n)
vc[i].clr();

rep(i, 0, n_) {
scanf("%lf %d %d %d", &F[i], &X[i], &Y[i], &R[i]);
if (F[i] == 400.0)
s = i;
else if (F[i] == 789.0)
t = i;
}

if (judge(s, t)) {
puts("Game is VALID");
continue;
}

rep(i, 0, n_) {
if (i!=s && i!=t)
addEdge(i<<1, i<<1|1, 1);
rep(j, 0, i) {
if (judge(i, j))
addEdge(i<<1|1, j<<1, 1);
else if (judge(j, i))
addEdge(j<<1|1, i<<1, 1);
}
}

addEdge(s<<1, s<<1|1, 2);

ans = EK(s<<1, t<<1);

if (ans >= 2)
puts("Game is VALID");
else
puts("Game is NOT VALID");
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: