time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Cthulhu decided to catch Scaygerboss. Scaygerboss found it out and is trying to hide in a pack of his scaygers. Each scayger except Scaygerboss is either a male or a female. Scaygerboss’s gender is “other”.
Scaygers are scattered on a two-dimensional map divided into cells. A scayger looks nerdy and loveable if it is staying in the same cell with exactly one scayger of a gender that is different from its own gender. Cthulhu will not be able to catch Scaygerboss if all the scaygers on the map look nerdy and loveable.
The scaygers can move around at different speeds. For each scayger, we are given the time it takes this scayger to move from a cell to an adjacent cell. Cells are adjacent if they share a common side. At any point of time, each cell that does not contain an obstacle can be occupied by an arbitrary number of scaygers. Scaygers cannot move to cells with obstacles.
Calculate minimal time in order to make all scaygers look nerdy and loveable if they move optimally toward this goal.
Input
The first line contains 4 integers: n, m, males, females (0 ≤ males, females ≤ n·m). n and m are dimensions of the map; males and females are numbers of male scaygers and female scaygers.
Next n lines describe the map. Each of these lines contains m characters. Character ‘.’ stands for a free cell; character ‘#’ stands for a cell with an obstacle.
The next line contains 3 integers r, c, and t (1 ≤ r ≤ n, 1 ≤ c ≤ m, 1 ≤ t ≤ 109): the current coordinates of Scaygerboss and the time it takes Scaygerboss to move to an adjacent cell. The next males lines contain coordinates and times of male scaygers in the same format as for Scaygerboss. The next females lines contain coordinates and times of female scaygers in the same format as for Scaygerboss. (The coordinates and times adhere to the same limits as for Scaygerboss.) All scaygers reside in cells without obstacles.
The problem consists of two subproblems. The subproblems have different constraints on the input. You will get some score for the correct submission of the subproblem. The description of the subproblems follows.
In subproblem F1 (14 points), the constraints 1 ≤ n, m ≤ 11 will hold.
In subproblem F2 (6 points), the constraints 1 ≤ n, m ≤ 22 will hold.
Output
Output the minimum possible time it takes to make all scaygers look nerdy and loveable or -1 if it is impossible.
分析
首先,如果男女数量差的绝对值不为1,或对数大于空位数,是无解的。
之后可以钦定Scaygerboss的性别以完成配对。
如果用搜索,状态太大无法完成。
但是可以考虑转变成判定性问题。
显然,如果答案为ans,大于ans的时间都是可以的。那么首先二分答案。
现在问题转化为,是否能在t时间内完成匹配。
那么可以先用bfs求出每个人到每个位置花费的时间。然后每个人、每个位置看作一个点,其中源点向男人连一条容量为1的边,女人向汇点连一条容量为1的边,如果一个人能在t时间内到达一个位置,就连一条容量为1的边。注意位置要拆点,控制流量为1。最终跑出最大流,如果等于人数即可以在t时间内完成匹配。
注意不连通的情况。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int w[4][2]={{-1,0},{1,0},{0,-1},{0,1}},maxn=2005,maxm=1100005;
typedef long long LL;
int n,m,A,B,tot,cnt,ans,t,h[maxn],e[maxm],next[maxm],ch[maxm],now[maxn],visit[maxn],f[maxn],data[505][2];
LL l,r,mid;
bool fl[maxm];
char map[25][25];
struct people
{
int x,y,t;
LL dis[505];
}boy[505],girl[505];
int get(int x,int y)
{
return x*m+y;
}
void add(int x,int y,bool f,int o)
{
e[++tot]=y; next[tot]=h[x]; fl[tot]=f; ch[tot]=tot+o; h[x]=tot;
}
bool aug(int x)
{
visit[x]=tot;
if (x==t) return 1;
for (int i=now[x];i;i=next[i])
{
if (fl[i] && visit[e[i]]<tot && f[x]==f[e[i]]+1)
{
if (aug(e[i]))
{
fl[i]=0; fl[ch[i]]=1; now[x]=next[i]; return 1;
}
}
}
return now[x]=0;
}
void flow()
{
memcpy(now,h,sizeof(now));
while (1)
{
tot++;
if (!aug(0)) break;
ans++;
}
}
bool check()
{
int tmp=1e9;
for (int x=0;x<=t;x++) if (visit[x]==tot)
{
for (int i=h[x];i;i=next[i])
{
if (fl[i] && visit[e[i]]<tot && tmp>f[e[i]]+1-f[x]) tmp=f[e[i]]+1-f[x];
}
}
if (tmp==1e9) return 0;
for (int i=0;i<=t;i++) if (visit[i]==tot) f[i]+=tmp;
return 1;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&A,&B);
for (int i=0;i<n;i++)
{
scanf("%s",&map[i]);
for (int j=0;j<m;j++) cnt+=(map[i][j]=='.');
}
if (abs(A-B)!=1 || max(A,B)>cnt)
{
printf("-1\n"); return 0;
}
if (A<B)
{
A++;
for (int i=0;i<A;i++) scanf("%d%d%d",&boy[i].x,&boy[i].y,&boy[i].t);
for (int i=0;i<B;i++) scanf("%d%d%d",&girl[i].x,&girl[i].y,&girl[i].t);
}else
{
B++;
scanf("%d%d%d",&girl[0].x,&girl[0].y,&girl[0].t);
for (int i=0;i<A;i++) scanf("%d%d%d",&boy[i].x,&boy[i].y,&boy[i].t);
for (int i=1;i<B;i++) scanf("%d%d%d",&girl[i].x,&girl[i].y,&girl[i].t);
}
t=((n*m+A)<<1)+1;
for (int i=0;i<A;i++)
{
memset(boy[i].dis,255,sizeof(boy[i].dis));
data[1][0]=boy[i].x-1; data[1][1]=boy[i].y-1;
boy[i].dis[get(data[1][0],data[1][1])]=0;
tot=1;
for (int j=1;j<=tot;j++)
{
for (int k=0;k<4;k++)
{
int p=data[j][0]+w[k][0],q=data[j][1]+w[k][1];
if (p>=0 && p<n && q>=0 && q<m && map[p][q]=='.' && boy[i].dis[get(p,q)]==-1)
{
boy[i].dis[get(p,q)]=boy[i].dis[get(data[j][0],data[j][1])]+boy[i].t;
data[++tot][0]=p; data[tot][1]=q;
}
}
}
r=max(r,boy[i].dis[get(data[tot][0],data[tot][1])]);
memset(girl[i].dis,255,sizeof(girl[i].dis));
data[1][0]=girl[i].x-1; data[1][1]=girl[i].y-1;
girl[i].dis[get(data[1][0],data[1][1])]=0;
tot=1;
for (int j=1;j<=tot;j++)
{
for (int k=0;k<4;k++)
{
int p=data[j][0]+w[k][0],q=data[j][1]+w[k][1];
if (p>=0 && p<n && q>=0 && q<m && map[p][q]=='.' && girl[i].dis[get(p,q)]==-1)
{
girl[i].dis[get(p,q)]=girl[i].dis[get(data[j][0],data[j][1])]+girl[i].t;
data[++tot][0]=p; data[tot][1]=q;
}
}
}
r=max(r,girl[i].dis[get(data[tot][0],data[tot][1])]);
}
for (l=0,mid=r>>1;l<r;mid=l+r>>1)
{
tot=0;
memset(h,0,sizeof(h));
for (int i=0;i<A;i++)
{
add(0,i+1,1,1); add(i+1,0,0,-1);
add(A+i+1,t,1,1); add(t,A+i+1,0,-1);
}
for (int i=0;i<n*m;i++) if (map[i/m][i%m]=='.')
{
int p=A+A+i+1,q=p+n*m;
add(p,q,1,1); add(q,p,0,-1);
for (int j=0;j<A;j++)
{
if (boy[j].dis[i]>-1 && boy[j].dis[i]<=mid)
{
add(j+1,p,1,1); add(p,j+1,0,-1);
}
if (girl[j].dis[i]>-1 && girl[j].dis[i]<=mid)
{
add(q,j+A+1,1,1); add(j+A+1,q,0,-1);
}
}
}
ans=tot=0;
memset(f,0,sizeof(f));
memset(visit,0,sizeof(visit));
for (flow();check();flow());
if (ans==A) r=mid;else l=mid+1;
}
tot=0;
memset(h,0,sizeof(h));
for (int i=0;i<A;i++)
{
add(0,i+1,1,1); add(i+1,0,0,-1);
add(A+i+1,t,1,1); add(t,A+i+1,0,-1);
}
for (int i=0;i<n*m;i++) if (map[i/m][i%m]=='.')
{
int p=A+A+i+1,q=p+n*m;
add(p,q,1,1); add(q,p,0,-1);
for (int j=0;j<A;j++)
{
if (boy[j].dis[i]>-1 && boy[j].dis[i]<=l)
{
add(j+1,p,1,1); add(p,j+1,0,-1);
}
if (girl[j].dis[i]>-1 && girl[j].dis[i]<=l)
{
add(q,j+A+1,1,1); add(j+A+1,q,0,-1);
}
}
}
ans=tot=0;
memset(f,0,sizeof(f));
memset(visit,0,sizeof(visit));
for (flow();check();flow());
if (ans==A) printf("%I64d\n",l);else printf("-1\n");
return 0;
}