真正的危机不是机器人像人一样思考,而是人像机器一样思考。 ——凉宫春日的忧郁

[补档]王者之剑

王者之剑

题目

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

 

posted @ 2017-08-03 07:19  Hzoi_Mafia  阅读(246)  评论(0编辑  收藏  举报
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。 ——死神