• [bzoj1066] [SCOI2007] 蜥蜴


    在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃
    到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石
    柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不
    变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个
    石柱上。

    Input

      输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱
    ,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。

    Output

      输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。

    Sample Input

    5 8 2
    00000000
    02000000
    00321100
    02000000
    00000000
    ........
    ........
    ..LLLL..
    ........
    ........

    Sample Output

    1

    题解:徐趱鹏大佬一眼看出了裂点,的确,这种题目,自己有一个承受量的,一般需要裂点成一个终点,一个起点,然后流量为承受量,

    然后就是S->入点无限流量,出点->终点无限流量去流。

    这一道题目,建模型不难,关键在于代码实现建边,十分复杂,参考了hzw。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<queue>
      6 #include<algorithm>
      7 #define N 1007
      8 #define inf 1000000007
      9 using namespace std;
     10 
     11 int r,c,d,S,T;
     12 int cnt=1,head[N],next[N*N],rea[N*N],val[N*N];
     13 int ans,mp[21][21],mark[21][21];
     14 int dis[N];
     15 
     16 void add(int u,int v,int fee)
     17 {
     18     cnt++;
     19     next[cnt]=head[u];
     20     head[u]=cnt;
     21     rea[cnt]=v;
     22     val[cnt]=fee;
     23 }
     24 bool judge(int x1,int y1,int x2,int y2)
     25 {
     26     if(((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))<=(d*d)&&mp[x1][y1]&&mp[x2][y2]) return 1;
     27     return 0;
     28 }
     29 void build()
     30 {
     31      for(int x1=1;x1<=r;x1++)
     32         for(int y1=1;y1<=c;y1++)
     33            for(int x2=x1-d;x2<=x1+d;x2++)
     34               for(int y2=y1-d;y2<=y1+d;y2++)
     35                    if(judge(x1,y1,x2,y2)&&(x1!=x2||y1!=y2)) add(mark[x1][y1]+r*c,mark[x2][y2],inf),add(mark[x2][y2],mark[x1][y1]+r*c,0); 
     36      for(int i=1;i<=r;i++)
     37         for(int j=1;j<=c;j++)
     38            if(mp[i][j])    add(mark[i][j],mark[i][j]+r*c,mp[i][j]),add(mark[i][j]+r*c,mark[i][j],0);
     39 }
     40 bool bfs()
     41 {
     42     memset(dis,-1,sizeof(dis));
     43     dis[S]=0;
     44     queue<int>q;
     45     q.push(S);
     46     while (!q.empty())
     47     {
     48         int u=q.front();
     49         q.pop();
     50         for (int i=head[u];i!=-1;i=next[i])
     51         {
     52             int v=rea[i],cost=val[i];
     53             if (dis[v]==-1&&cost>0)
     54             {
     55                 dis[v]=dis[u]+1;
     56                 if (v==T) return 1;
     57                 q.push(v);
     58             }
     59         }
     60     }
     61     return 0;
     62 }
     63 int dfs(int u,int MM)
     64 {
     65     int res=0;
     66     if (u==T||MM==0) return MM;
     67     for (int i=head[u];i!=-1;i=next[i])
     68     {
     69         int v=rea[i],fee=val[i];
     70         if (dis[v]!=dis[u]+1) continue;
     71         int x=dfs(v,min(MM,fee));
     72         if (x)
     73         {
     74             val[i]-=x,val[i^1]+=x;
     75             MM-=x,res+=x;
     76             if (MM==0) break;
     77         }
     78     }
     79     return res;
     80 }
     81 int dinic()
     82 {
     83     int res=0;
     84     while (bfs())
     85     {
     86         int x=dfs(S,inf);
     87         while (x)
     88         {
     89             res+=x;
     90             x=dfs(S,inf);
     91         }
     92     }
     93     return res;
     94 }
     95 int main()
     96 {
     97     memset(head,-1,sizeof(head));
     98     scanf("%d%d%d",&r,&c,&d);
     99     int INK=r*c;
    100     S=INK*2+1,T=INK*2+2;
    101     char ch[21];
    102     for(int i=1;i<=r;i++)
    103     {
    104        scanf("%s",ch+1);
    105        for(int j=1;j<=c;j++)
    106            mp[i][j]=ch[j]-'0';
    107     }
    108     int tot=0;
    109     for(int i=1;i<=r;i++)
    110         for(int j=1;j<=c;j++)
    111               tot++,mark[i][j]=tot; 
    112     for(int i=1;i<=r;i++)
    113     {
    114        scanf("%s",ch+1);
    115        for(int j=1;j<=c;j++)
    116            if(ch[j]=='L') {add(S,mark[i][j],1),add(mark[i][j],S,0);ans++;}
    117     }
    118     for(int i=1;i<=d;i++)
    119        for(int j=d+1;j<=r-d;j++)
    120        {
    121           add(mark[j][i]+INK,T,inf),add(T,mark[j][i]+INK,0);
    122           add(mark[j][c-i+1]+INK,T,inf),add(T,mark[j][c-i+1]+INK,0);
    123        }
    124     for(int i=1;i<=d;i++)
    125        for(int j=1;j<=c;j++)
    126        {
    127           add(mark[i][j]+INK,T,inf),add(T,mark[i][j]+INK,0);
    128           add(mark[r-i+1][j]+INK,T,inf),add(T,mark[r-i+1][j]+INK,0);
    129        }
    130     build();
    131     int res=dinic();
    132     printf("%d",ans-res);
    133 }
  • 相关阅读:
    【Unity】自定义编辑器窗口——拓展编辑器功能
    【Unity】AssetBundle的使用——打包/解包
    【Unity】使用Resources类管理资源
    【Unity】使用AssetDatabase编辑器资源管理
    【Unity】协程Coroutine及Yield常见用法
    【Unity】制作简易定时器(Timer)
    python3使用csv模块读写csv文件
    Python3使用csv模块csv.writer().writerow()保存csv文件,产生空行的问题
    MongoDB服务无法启动,发生服务特定错误:100
    ValueError: update only works with $ operators
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7598870.html
Copyright © 2020-2023  润新知