王者之剑
★★★☆ 输入文件:Excalibur.in
输出文件:Excalibur.out
简单对比 时间限制:1 s 内存限制:256 MB
【题目描述】
这是在阿尔托利亚·潘德拉贡成为英灵前的事情,她正要去拔出石中剑成为亚瑟王,在这之前她要去收集一些宝石。
宝石排列在一个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
疯狂分奇偶点!!!
偶点与四周建边
S->偶点-》四周奇点-》T
翻转源汇 S 要偶 T要奇
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<queue> #include<map> #include<cstdlib> #include<algorithm> #define V 105 #define mod 1000000007 #define LL long long using namespace std; int n,m,sd,T,S; int a[V][V],s[V][V],g[V][V],pre[V*V],dep[V*V],q[V*V]; struct da { int to,next,dis; }Edge[V*V*V]; int head[V*V],tot; inline void add(int x,int y,int zz) { Edge[tot].to=y; Edge[tot].dis=zz; Edge[tot].next=head[x]; head[x]=tot++; Edge[tot].to=x; Edge[tot].dis=0; Edge[tot].next=head[y]; head[y]=tot++; } bool Bfs() { memset(dep, 0, sizeof(dep)); int hd,tl; hd = tl = 0; q[++ tl] = S, dep[S] = 1; while(hd<tl) { int op = q[++hd]; for(int i = head[op] ; i != -1 ; i = Edge[i].next) { if(Edge[i].dis&&(!dep[Edge[i].to])) { dep[Edge[i].to] = dep[op]+1; q[++ tl] = Edge[i].to; if(Edge[i].to==T) return true; } } } return false; } int Dfs(int op, int fw) { if(op==T) return fw; int tmp =fw,k; for(int i = head[op] ; i != -1 ; i = Edge[i].next) { if(Edge[i].dis&&tmp&&dep[Edge[i].to]==dep[op]+1) { k = Dfs(Edge[i].to, min(Edge[i].dis, tmp)); if(!k) { dep[Edge[i].to] = 0; continue; } Edge[i].dis-= k, Edge[i^1].dis+= k,tmp-= k; } } return fw-tmp; } int solve() { int i,flow=0; while(Bfs()) { flow+=Dfs(S,mod); } return flow; } inline int haha() { // freopen("in.txt","r",stdin);freopen("out.txt","w",stdout); freopen("Excalibur.in","r",stdin); freopen("Excalibur.out","w",stdout); memset(head,-1,sizeof(head)); cin>>n>>m; //cout<<n<<" ! "<<m<<endl; int num=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { sd++; g[i][j]=sd; cin>>a[i][j]; s[i][j]=num; num^=1; //cout<<g[i][j]<<" "; } num=s[i][1]^1; // num^=1; //cout<<endl; } T=g[n][m]+1; num=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(s[i][j]) { add(0,g[i][j],a[i][j]); if(i>1) add(g[i][j],g[i-1][j],mod); if(i<n) add(g[i][j],g[i+1][j],mod); if(j>1) add(g[i][j],g[i][j-1],mod); if(j<m) add(g[i][j],g[i][j+1],mod); } else { add(g[i][j],T,a[i][j]); } num+=a[i][j]; } } printf("%d",num-solve()); return 0; } int gg=haha(); int main() {;}