• cogs 2051. 王者之剑


    【题目描述】

    这是在阿尔托利亚·潘德拉贡成为英灵前的事情,她正要去拔出石中剑成为亚瑟王,在这之前她要去收集一些宝石。

    宝石排列在一个n*m的网格中,每个网格中有一块价值为v(i,j)的宝石,阿尔托利亚·潘德拉贡可以选择自己的起点。

    开始时刻为0秒。以下操作,每秒按顺序执行

    1.在第i秒开始的时候,阿尔托利亚·潘德拉贡在方格(x,y)上,她可以拿走(x,y)中的宝石。

    2.在偶数秒,阿尔托利亚·潘德拉贡周围四格的宝石会消失

    3.若阿尔托利亚·潘德拉贡第i秒开始时在方格(x,y)上,则在第i+1秒可以立即移动到(x+1,y),(x,y+1),(x-1,y)或(x,y-1)上,也可以停留在(x,y)上。

    求阿尔托利亚·潘德拉贡最多可以获得多少价值的宝石

    【输入格式】

    第一行给出数字N,M代表行列数.N,M均小于等于100,宝石的价值不会超过10000.下面N行M列用于描述数字矩阵

    【输出格式】

    输出最多可以拿到多少价值宝石

    【样例输入】

    2 2

    1 2

    2 1

    【样例输出】

    4

    【提示】

    在此键入。

    【来源】

    姚金宇的原创题,有修改

    solution:

    明确两条性质:

    1.一个宝石只能在偶数时刻被吃掉

    2.最终的结果与起始位置无关

    那么我们可以将矩阵像棋盘上一样黑白染色

    由于如果一个点被吃,那么它周围的点一定不能被吃

    所以将黑点与S(起点)连 v=1的边  将白点与T(终点)连 v=1的边 将黑点周围的4个(或不到4个)白点连 v=INF的边

    最后用最大流求最小割即可

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #define mem(a,b) memset(a,b,sizeof(a))
      5 using namespace std;
      6 const int INF=(1<<31)-1;
      7 inline int minn(int a,int b){return a<b?a:b;}
      8 struct son
      9 {
     10     int v,next,w,u;
     11 };
     12 son a1[500001];
     13 int first[500001],e;
     14 
     15 void addbian(int u,int v,int w)
     16 {
     17     a1[e].u=u;
     18     a1[e].v=v;
     19     a1[e].w=w;
     20     a1[e].next=first[u];
     21     first[u]=e++;
     22 }
     23 
     24 int dui[10000001],he,en;
     25 inline void clear(){he=1;en=0;}
     26 inline void push(int x){dui[++en]=x;}
     27 inline int top(){return dui[he];}
     28 inline void pop(){++he;}
     29 inline bool empty(){return en>=he?0:1;}
     30 
     31 int n,m,u,o,S,T,sum;
     32 int ji[101][101];
     33 int hh[101][101];
     34 
     35 int dep[20001];
     36 int bfs()
     37 {
     38     mem(dep,0);clear();
     39     dep[S]=1;push(S);
     40     while(!empty())
     41     {
     42         int now=top();pop();
     43         //printf("now=%d
    ",now);
     44         for(int i=first[now];i!=-1;i=a1[i].next)
     45         {
     46             int temp=a1[i].v;
     47             //printf("temp=%d
    ",temp);
     48             if(!a1[i].w||dep[temp])continue;
     49             dep[temp]=dep[now]+1;
     50             push(temp);
     51             if(temp==T)return 1;
     52         }
     53     }
     54     return 0;
     55 }
     56 
     57 int dfs(int x,int val)
     58 {
     59     //printf("x=%d
    ",x);
     60     if(x==T)return val;
     61     int val2=val,k;
     62     for(int i=first[x];i!=-1;i=a1[i].next)
     63     {
     64         int temp=a1[i].v;
     65         //printf("temp=%d
    ",temp);
     66         if(dep[temp]!=dep[x]+1||!a1[i].w||!val2)continue;
     67         k=dfs(temp,minn(val2,a1[i].w));
     68         if(!k){dep[temp]=0;continue;}
     69         a1[i].w-=k;a1[i^1].w+=k;val2-=k;
     70     }
     71     return val-val2;
     72 }
     73 
     74 int Dinic()
     75 {
     76     int ans=0;
     77     while(bfs())
     78       ans+=dfs(S,INF);
     79     return ans;
     80 }
     81 
     82 void out11()
     83 {
     84     printf("
    ");
     85     /*for(int i=1;i<=n;++i)
     86     {
     87         for(int j=1;j<=m;++j)
     88           printf("%d ",ji[i][j]);
     89         printf("
    ");
     90     }*/
     91     for(int i=S;i<=T;++i)
     92     {
     93         printf("i=%d
    ",i);
     94         for(int j=first[i];j!=-1;j=a1[j].next)
     95           printf("%d ",a1[j].v);
     96         printf("
    ");
     97     }
     98     printf("
    ");
     99 }
    100 
    101 int main(){
    102     //freopen("1.txt","r",stdin);
    103     freopen("Excalibur.in","r",stdin);
    104     freopen("Excalibur.out","w",stdout);
    105     mem(first,-1);
    106     scanf("%d%d",&n,&m);
    107     S=0;T=n*m+1;
    108     for(int i=1;i<=m;++i)
    109         ji[1][i]=i&1;
    110     for(int i=2;i<=n;++i)
    111     {
    112         ji[i][1]=ji[i-1][2];
    113         for(int j=2;j<=m;++j)
    114           ji[i][j]=ji[i-1][j-1];
    115     }
    116     
    117     for(int i=1;i<=n;++i)
    118       for(int j=1;j<=m;++j)
    119         hh[i][j]=(i-1)*m+j;
    120     
    121     //out11();
    122     
    123     for(int i=1;i<=n;++i)
    124       for(int j=1;j<=n;++j)
    125       {
    126             scanf("%d",&u);
    127             sum+=u;
    128             if(ji[i][j])
    129             {
    130                 addbian(S,hh[i][j],u);
    131                 addbian(hh[i][j],S,0);
    132             }
    133             else
    134             {
    135                 addbian(hh[i][j],T,u);
    136                 addbian(T,hh[i][j],0);
    137             }
    138         }
    139     
    140     //out11();
    141     
    142     for(int i=1;i<=n;++i)
    143       for(int j=1;j<=m;++j)
    144         if(ji[i][j])
    145         {
    146                 if(i>1)
    147                 {
    148                     addbian(hh[i][j],hh[i-1][j],INF);
    149                     addbian(hh[i-1][j],hh[i][j],0);
    150                 }
    151                 if(i<n)
    152                 {
    153                     addbian(hh[i][j],hh[i+1][j],INF);
    154                     addbian(hh[i+1][j],hh[i][j],0);
    155                 }
    156                 if(j>1)
    157                 {
    158                     addbian(hh[i][j],hh[i][j-1],INF);
    159                     addbian(hh[i][j-1],hh[i][j],0);
    160                 }
    161                 if(j<m)
    162                 {
    163                     addbian(hh[i][j],hh[i][j+1],INF);
    164                     addbian(hh[i][j+1],hh[i][j],0);
    165                 }
    166             }
    167     
    168     //out11();
    169     
    170     //cout<<0;
    171     printf("%d",sum-Dinic());
    172     //while(1);
    173     return 0;
    174 }
    code
  • 相关阅读:
    打印空格
    进程间的通信
    堆排序算法
    大小端的判断
    bash help
    [Android] How to disable the screen orientation?
    图片的静态动态显示效果
    WPF Threads: Build More Responsive Apps With The Dispatcher
    用node.js+express自建网站发布静态网页
    利用Apache mod_expires 与 mod_headers 实现文件缓存及mod_deflate压缩输出
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7257253.html
Copyright © 2020-2023  润新知