蜥蜴 【有圖包懂】 (網絡流) gzoi

廣州的同學看這裏:

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;
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章