廣州的同學看這裏:
http://www.gdgzoi.com/JudgeOnline/problem.php?cid=1045&pid=3
Description
在一個r行c列的網格地圖中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任務是讓儘量多的蜥蜴逃到邊界外。
每行每列中相鄰石柱的距離爲1,蜥蜴的跳躍距離是d,即蜥蜴可以跳到平面距離不超過d的任何一個石柱上。石柱都不穩定,每次當蜥蜴跳躍時,所離開的石柱高度減1(如果仍然落在地圖內部,則到達的石柱高度不變),如果該石柱原來高度爲1,則蜥蜴離開後消失。以後其他蜥蜴不能落腳。任何時刻不能有兩隻蜥蜴在同一個石柱上。
【輸入】第一行爲三個整數r,c,d,即地圖的規模與最大跳躍距離。以下r行爲石竹的初始狀態,0表示沒有石柱,1~3表示石柱的初始高度。以下r行爲蜥蜴位置,“L”表示蜥蜴,“.”表示沒有蜥蜴。
【輸出】僅一行,包含一個整數,即無法逃離的蜥蜴總數的最小值。
【樣例】
Xyz.in |
Xyz.out |
5 8 2 00000000 02000000 00321100 02000000 00000000 ........ ........ ..LLLL.. ........ ........ |
1 |
【限制】
100%的數據滿足:1<=r, c<=20, 1<=d<=3
題目數據很小,所以做起來會很輕鬆(EK就行了)
接下來就是思路:一看就知道是網絡流的題目。
1.首先是蜥蜴,與超源點連接,容量爲一。
2.其次是石柱,每次有蜥蜴經過時高度減一,拆分成兩點容量爲石柱高度。
3.石柱與可以連接的石柱相連,容量爲INF。
4.可以直接跳出的石柱與匯點相連,容量INF,石柱高度都行。
如果還不明白的看下面圖:
石柱拆分我就沒畫了,看上面自己腦補一下,就像你們看番的時候就行
接下來就是貼代碼了:
#include<iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define MAXN 1050
#define MAXQ 20050
#define INF 999999
using namespace std;
int r,c,d,cnt=0,acnt=0,ans=0;
int num[21][21];//用來記錄每個有石柱的點的編號;
int a[MAXQ];
int map[MAXN][MAXN],in[25][25];//map是矩陣圖,記錄點與點聯繫;in是石柱高度;
int p[MAXQ],q[MAXQ];
void makePic(int x,int y)//搜索有直接聯繫的邊建圖;
{int i,j;
int now=num[x][y]+1;
for(i=1;i<=r;i++)
for(j=1;j<=c;j++)
{
if((i!=x||j!=y) && (in[i][j]>0) && d*d>=(x-i)*(x-i)+(y-j)*(y-j))
map[now][num[i][j]]=INF;
}
}
void escape()//判斷該石柱是否可以出逃;
{int i,j;
for(i=1;i<=r;i++)
for(j=1;j<=c;j++)
if(i-d<1||i+d>r||j-d<1||j+d>c)
{
int now=num[i][j]+1;
map[now][cnt]=INF;
}
}
int Maxflow() //模板;
{int flow=0;
for(;;)
{ queue<int> Q;
memset(p,-1,sizeof(p));
Q.push(0);
while(!Q.empty())
{int now=Q.front();Q.pop();
for(int i=1;i<=cnt;i++)
if(p[i]<0 && map[now][i]>0)
{Q.push(i);
p[i]=now;
}
if(p[cnt]>0) break;
}
if(p[cnt]<0) break;
int minFlow=INF;
for(int i=cnt;i!=0;i=p[i])
minFlow=min(minFlow,map[p[i]][i]);
for(int i=cnt;i!=0;i=p[i])
{ map[p[i]][i]-=minFlow;
map[i][p[i]]+=minFlow;
}
flow+=minFlow;
}
return flow;
}
void init()
{
int i,j;
char s;
cin>>r>>c>>d;
for(i=1;i<=r;i++)
for(j=1;j<=c;j++)
{cin>>s;
in[i][j]=s-48;//石柱高度(該點是否有石柱);
if(s!='0')
{num[i][j]=++cnt;
map[cnt][cnt+1]=s-48;
cnt++;}//石柱拆成倆點;
}
for(i=1;i<=r;i++)
for(j=1;j<=c;j++)
{cin>>s;
if(s=='L')
{acnt++;
map[0][num[i][j]]=1;//有蜥蜴的與源點連接;
}
if(in[i][j]>0)
makePic(i,j);//每個石柱遍歷建圖(數據小);
}
}
int main()
{
init();
cnt++;
escape();
cout<<acnt-Maxflow()<<endl;
return 0;
}