分类
标签
2-SAT AC自动机 BFS CDQ dfs DP fail树 FFT FFT&NTT FWT hash KD-Tree KMP LCA SPFA STL Tarjan Treap Trie 主席树 乱搞 二分 二分图匹配 二分答案 二维SPFA 交互 位运算 其他 最小生成树 分块 区间DP 半平面交 博弈论 可持久化 可持久化Trie树 后缀数组 图库 平衡树 并查集 插头DP 数学 数论 无旋Treap 日记 暴力 权值树状数组 栈 树DP 树套树 树状数组 树贪心 概率DP 模拟 欧拉定理 点分治 状压DP 生成函数 矩阵乘 线性规划 线段树 组合 网络流 群论 莫比乌斯反演 计算几何 贪心 费用流 高斯消元
564 字
3 分钟
[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
与网络流24题中方格取数相同
最大权闭合子图
黑白染色
相邻连INF的边
源点向白格子连格子权值的边
黑格子想汇点连权值的边
跑一遍最小割也就是最大流 Dinic解决
/*
* @Author: WildRage
* @Date: 2017-06-13 16:37:09
* @Last Modified by: WildRage
* @Last Modified time: 2017-06-13 16:37:09
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int INF=0x7fffffff;
struct edge{
int END,cap,next;
}v[500000];
int first[10005],p;
void add(int a,int b,int c){
v[p].END=b;v[p].next=first[a];v[p].cap=c;first[a]=p++;
v[p].END=a;v[p].next=first[b];v[p].cap=0;first[b]=p++;
}
int dis[10005];
bool vis[10005];
bool BFS(int S,int E){
memset(vis,0,sizeof(vis));
memset(dis,-1,sizeof(dis));
queue<int> Q;
Q.push(S);
dis[S]=0;vis[S]=1;
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=first[u];i!=-1;i=v[i].next){
if(!vis[v[i].END]&&v[i].cap>0){
vis[v[i].END]=1;
dis[v[i].END]=dis[u]+1;
if(v[i].END==E)return 1;
Q.push(v[i].END);
}
}
}
return 0;
}
int DFS(int x,int a,int E){
if(x==E||a==0)return a;
int flow=0,f;
for(int i=first[x];i!=-1;i=v[i].next){
if(dis[x]+1==dis[v[i].END]&&(f=DFS(v[i].END,min(a,v[i].cap),E))>0){
v[i].cap-=f;
v[i^1].cap+=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
if(!flow)dis[x]=-1;
return flow;
}
int Dinic(int S,int E){
int flow=0;
while(BFS(S,E)){
flow+=DFS(S,INF,E);
}
return flow;
}
int a[105][105];
template<class T>inline void read(T &res){
static char ch;T flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-48;res*=flag;
}
int Main(){
freopen("Excalibur.in","r",stdin);
freopen("Excalibur.out","w",stdout);
memset(first,-1,sizeof(first));
int m,n;
int sum=0;
read(m),read(n);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++){
read(a[i][j]);
sum+=a[i][j];
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if((i&1)^(j&1)){
add(0,n*(i-1)+j,a[i][j]);
if(j-1>=1)add(n*(i-1)+j,n*(i-1)+j-1,INF);
if(i-1>=1)add(n*(i-1)+j,n*(i-2)+j,INF);
if(i+1<=m)add(n*(i-1)+j,n*(i)+j,INF);
if(j+1<=n)add(n*(i-1)+j,n*(i-1)+j+1,INF);
}
else{
add(n*(i-1)+j,n*m+1,a[i][j]);
}
}
}
return printf("%d",sum-Dinic(0,m*n+1));
}
int A=Main();
int main(){;}
[COGS 2051] 王者之剑 题解 网络流最大权闭合子图
https://www.nekomio.com/posts/5/