zoukankan      html  css  js  c++  java
  • [补档]王者之剑

    王者之剑

    题目

    这是在阿尔托利亚·潘德拉贡成为英灵前的事情,她正要去拔出石中剑成为亚瑟王,在这之前她要去收集一些宝石。
    宝石排列在一个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)上。
    求阿尔托利亚·潘德拉贡最多可以获得多少价值的宝石

    INPUT

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

    OUTPUT

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

    SAMPLE

    INPUT

    2 2
    1 2
    2 1

    OUTPUT

    4

    解题报告

    算是基础的最小割问题。
    首先,我们取值时一定是在偶数时刻,取走一个格子的值,就不能取相邻格子的值,也就是相邻格子之间的值是不相容的。
    我们想,只要取得格子相容,是一定有合法路径的,有不容的点就转化到最小割上,用总值减去割掉最小的值,就是最优解。
    那么我们可以黑白染色,源点与白点相连,黑点与汇点连边,不相容的点之间连边,容量INF,跑最小割即可
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<queue>
      5 using namespace std;
      6 inline int read(){
      7     int sum(0);
      8     char ch(getchar());
      9     for(;ch<'0'||ch>'9';ch=getchar());
     10     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     11     return sum;
     12 }
     13 struct edge{
     14     int e,n,w;
     15 }a[2000001];
     16 int pre[100001],tot;
     17 inline void insert(int s,int e,int w){
     18     a[tot].e=e;
     19     a[tot].w=w;
     20     a[tot].n=pre[s];
     21     pre[s]=tot++;
     22 }
     23 int n,m;
     24 int w[105][105],col[105][105];
     25 inline void paint(){
     26     int now(1);
     27     for(int i=1;i<=n;i++){
     28         now^=1;
     29         for(int j=1;j<=m;j++){
     30             if(j&1)
     31                 col[i][j]=now;
     32             else
     33                 col[i][j]=now^1;
     34         }
     35     }
     36 }
     37 int S(0),T;
     38 int ans(0),inf(0x7fffffff),sum(0);
     39 inline void build(){
     40     for(int i=1;i<=n;i++)
     41         for(int j=1;j<=m;j++){
     42             if(col[i][j])
     43                 insert(S,(i-1)*m+j,w[i][j]),insert((i-1)*m+j,S,0);
     44             else
     45                 insert((i-1)*m+j,T,w[i][j]),insert(T,(i-1)*m+j,0);
     46         }
     47     for(int i=1;i<=n;i++)
     48         for(int j=1;j<=m;j++){
     49             if(col[i][j]){
     50                 if(i!=1)
     51                     insert((i-2)*m+j,(i-1)*m+j,0),insert((i-1)*m+j,(i-2)*m+j,inf);
     52                 if(i!=n)
     53                     insert(i*m+j,(i-1)*m+j,0),insert((i-1)*m+j,i*m+j,inf);
     54                 if(j!=1)
     55                     insert((i-1)*m+j-1,(i-1)*m+j,0),insert((i-1)*m+j,(i-1)*m+j-1,inf);
     56                 if(j!=m)
     57                     insert((i-1)*m+j+1,(i-1)*m+j,0),insert((i-1)*m+j,(i-1)*m+j+1,inf);
     58             }
     59         }
     60 }
     61 int dis[10010];
     62 inline bool bfs(int s,int t){
     63     memset(dis,0,sizeof(dis));
     64     dis[s]=1;
     65     queue<int>q;
     66     q.push(s);
     67     while(!q.empty()){
     68         int k(q.front());
     69         q.pop();
     70         for(int i=pre[k];i!=-1;i=a[i].n){
     71             int e(a[i].e);
     72             if(!dis[e]&&a[i].w){
     73                 dis[e]=dis[k]+1;
     74                 q.push(e);
     75                 if(e==t)
     76                     return true;
     77             }
     78         }
     79     }
     80     return false;
     81 }
     82 inline int my_min(int a,int b){
     83     return a<b?a:b;
     84 }
     85 inline int dfs(int now,int flow){
     86     if(now==T)
     87         return flow;
     88     int tmp(flow),f;
     89     for(int i=pre[now];i!=-1;i=a[i].n){
     90         int e(a[i].e);
     91         if(dis[e]==dis[now]+1&&tmp&&a[i].w){
     92             f=dfs(e,my_min(tmp,a[i].w));
     93             if(!f){
     94                 dis[e]=0;
     95                 continue;
     96             }
     97             a[i].w-=f;
     98             a[i^1].w+=f;
     99             tmp-=f;
    100         }
    101     }
    102     return flow-tmp;
    103 } 
    104 inline int gg(){
    105     freopen("Excalibur.in","r",stdin);
    106     freopen("Excalibur.out","w",stdout);
    107     memset(pre,-1,sizeof(pre));
    108     n=read(),m=read();
    109     T=n*m+1;
    110     for(int i=1;i<=n;i++)
    111         for(int j=1;j<=m;j++)
    112             w[i][j]=read(),sum+=w[i][j];
    113     paint();
    114     build();
    115     while(bfs(S,T))
    116         ans+=dfs(S,inf);
    117     printf("%d",sum-ans);
    118     return 0;
    119 }
    120 int K(gg());
    121 int main(){;}
    View Code
  • 相关阅读:
    学习shell脚本
    Python 3.3.2 round函数并非"四舍五入"
    Python 通过继承实现标准对象的子类
    Python 继承标准类时发生了什么
    Python 表示无穷大的数
    用Python最原始的函数模拟eval函数的浮点数运算功能(2)
    Python 函数参数*expression 之后为什么只能跟关键字参数
    RE模块疑问
    用Python最原始的函数模拟eval函数的浮点数运算功能
    Python 好用得让人发指的函数参数语法糖
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7277689.html
Copyright © 2011-2022 走看看