COJ 0501 取数游戏(TPM)
取数游戏(TPM) |
难度级别:D; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B |
试题描述
|
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能有公共边,并且取出的数的和最大。(二分图匹配练习) |
输入
|
第一行是一个正整数n (n<20)。
接下来是 n*n 个非负数。 |
输出
|
输出可能取得的最大的和。
|
输入示例
|
3
5 9 4 8 3 6 2 7 1 |
输出示例
|
30
|
其他说明
|
n<20
|
题解:“没有公共边”这是赤裸裸的二分图呀!随便按(i+j)&1造个二分图跑了就行。。。
而且,这是我第一个接触的构造题吧= = 还是非常有纪念意义的= =我记得当年还是小健建给我亲自敲了一遍DInic然后敲了一遍这道题。。。回忆满满呢~
现在老练的ISAP+缩行:
//这两道题有什么区别。。。= =
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=+,maxm=+,inf=-1u>>;
struct ISAP{
struct tedge{int x,y,w,next;}adj[maxm];int ms,fch[maxn];
int d[maxn],s[maxn],cur[maxn],gap[maxn],n,top;
void init(int n){
this->n=n;ms=;top=;
memset(d,-,sizeof(d));
memset(fch,-,sizeof(fch));
return;
}
void addedge(int u,int v,int w){
adj[ms]=(tedge){u,v,w,fch[u]};fch[u]=ms++;
adj[ms]=(tedge){v,u,,fch[v]};fch[v]=ms++;
return;
}
void bfs(){
queue<int>Q;Q.push(n);d[n]=;
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=fch[u];i!=-;i=adj[i].next){
int v=adj[i].y;
if(d[v]==-) d[v]=d[u]+,Q.push(v);
}
} return;
}
int maxflow(int S,int T){
n=T;bfs();int k=S,i,flow=;
for(i=;i<=n;i++) cur[i]=fch[i],gap[d[i]]++;
while(d[S]<n){
if(k==n){
int mi=inf,pos;
for(i=;i<top;i++) if(adj[s[i]].w<mi) mi=adj[s[i]].w,pos=i;
for(i=;i<top;i++) adj[s[i]].w-=mi,adj[s[i]^].w+=mi;
flow+=mi;top=pos;k=adj[s[top]].x;
}
for(i=cur[k];i!=-;i=adj[i].next){
int v=adj[i].y;
if(adj[i].w&&d[k]==d[v]+){cur[k]=i;k=v;s[top++]=i;break;}
}
if(i==-){
int lim=n;
for(i=fch[k];i!=-;i=adj[i].next){
int v=adj[i].y;
if(adj[i].w&&d[v]<lim) lim=d[v],cur[k]=i;
} if(--gap[d[k]]==) break;
d[k]=lim+;gap[d[k]]++;
if(k!=S) k=adj[s[--top]].x;
}
} return flow;
}
}sol;
inline int read(){
int x=,sig=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-;ch=getchar();}
while(isdigit(ch)) x=*x+ch-'',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<) putchar('-'),x=-x;
int len=,buf[];while(x) buf[len++]=x%,x/=;
for(int i=len-;i>=;i--) putchar(buf[i]+'');return;
}
int A[][],mx[]={,-,,},my[]={,,-,};
void init(){
int n=read();long long ans=;
sol.init(n*n+);int S=n*n+,T=n*n+;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
A[i][j]=read();
if((i+j)&){
sol.addedge(S,i*n+j-n,A[i][j]);
for(int d=;d<;d++){
int nx=i+mx[d],ny=j+my[d];
if(nx>=&&nx<=n&&ny>=&&ny<=n) sol.addedge(i*n+j-n,nx*n+ny-n,inf);
}
}
else sol.addedge(i*n+j-n,T,A[i][j]);
ans+=A[i][j];
}
write(ans-sol.maxflow(S,T));
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){
init();work();print();return ;
}
当时最稚嫩的代码。。。真的有种说不出的感动:
#include <iostream>
#include <queue>
using namespace std; const int maxn = + ;
const int maxm = + ; struct Edge
{
int from, to, cap, flow;
}; struct Dinic
{
int n, m, s, t;
int first[maxn], next[maxm]; Edge edges[maxm]; void init(int n)
{
this -> n = n;
m = ; memset(first, -, sizeof(first)); return ;
} void AddEdge(int from, int to, int cap)
{
edges[m] = (Edge){from, to, cap, };
next[m] = first[from];
first[from] = m++; edges[m] = (Edge){to, from, , };
next[m] = first[to];
first[to] = m++; return ;
} int d[maxn], cur[maxn];
bool vis[maxn]; int BFS()
{
memset(vis, , sizeof(vis));
queue<int> Q; Q.push(s);
vis[s] = true;
d[s] = ; while(!Q.empty())
{
int x = Q.front(); Q.pop(); for(int i = first[x]; i != -; i = next[i])
{
Edge& e = edges[i];
if(!vis[e.to] && e.cap > e.flow)
{
vis[e.to] = true;
d[e.to] = d[x] + ;
Q.push(e.to);
}
}
} return vis[t];
}
int DFS(int x, int a)
{
if(x == t || !a) return a; int f, flow = ; for(int& i = cur[x]; i != -; i = next[i])
{
Edge& e = edges[i];
if(d[e.to] == d[x] + && (f = DFS(e.to, min(a, e.cap - e.flow))) > )
{
flow += f;
a -= f;
e.flow += f;
edges[i ^ ].flow -= f;
if(!a) break;
}
}
return flow;
} int MaxFlow(int s, int t)
{
this -> s = s;
this -> t = t; int flow = ; while(BFS())
{
for(int i = ; i < n; i++) cur[i] = first[i];
flow += DFS(s, );
}
return flow; //你大爷!!!!!!!!!!!!!!!!
}
}sol; int a[][];
int nx[] = {, , -, };
int ny[] = {-, , , }; int main()
{
int n, m;
scanf("%d", &n); m = n; sol.init(n * m + ); long long double tot = ; int s = n * m;
int t = n * m + ; for(int i = ; i < n; i++)
for(int j = ; j < m; j++)
{
scanf("%d", &a[i][j]);
tot += a[i][j];
if((i + j) & )
{
sol.AddEdge(s, i * m + j, a[i][j]); for(int d = ; d < ; d++)
{
int mx = nx[d] + i;
int my = ny[d] + j; if(mx >= && mx < n && my >= && my < m)
{
sol.AddEdge(i * m + j, mx * m + my, );
}
}
}
else sol.AddEdge(i * m + j, t, a[i][j]);
} printf("%d\n", tot - sol.MaxFlow(s, t));
//system("pause");
return ;
}
搜索
复制
COJ 0501 取数游戏(TPM)的更多相关文章
- NOIP2007 矩阵取数游戏
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- 1166 矩阵取数游戏[区间dp+高精度]
1166 矩阵取数游戏 2007年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description [ ...
- 矩阵取数游戏 NOIP 2007
2016-05-31 17:26:45 题目链接: NOIP 2007 矩阵取数游戏(Codevs) 题目大意: 给定一个矩阵,每次在每一行的行首或者行尾取一个数乘上2^次数,求取完最多获得的分数 解 ...
- 洛谷 P1005 矩阵取数游戏
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- BZOJ1978: [BeiJing2010]取数游戏 game
1978: [BeiJing2010]取数游戏 game Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 650 Solved: 400[Submit] ...
- codevs1166 矩阵取数游戏
题目描述 Description [问题描述] 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均 为非负整数.游戏规则如下: 1. 每次取数时须从每行各取走一个 ...
- BZOJ 1978: [BeiJing2010]取数游戏 game( dp )
dp(x)表示前x个的最大值, Max(x)表示含有因数x的dp最大值. 然后对第x个数a[x], 分解质因数然后dp(x) = max{Max(t)} + 1, t是x的因数且t>=L -- ...
- 矩阵取数游戏洛谷p1005
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...
- 计蒜客 取数游戏 博弈+dp
题目链接 取数游戏 思路:dp(x, y)表示先手在区间[x, y]能取得的最大分数.当先手取完,就轮到后手去,后手一定会选择当前能令他得到最大分数的策略,其实当先手在[x, y]区间两端取走一个数, ...
随机推荐
- IOS UIButton使用详解
第一.UIButton的定义 UIButton *button=[[UIButton buttonWithType:(UIButtonType); 能够定义的button类型有以下6种, typede ...
- Javascript 控制style 小结
style.top 如: c.style.top=scrollTop; 在IE各版本中可以,Safari, chrome, Firefox都不work, 需要在后面 + "px";
- Day11 - Mysql and ORM
python 之路,Day11 - python mysql and ORM 本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 ...
- windows服务安装(System.ComponentModel.Win32Exception:远程过程调用失败)
“安装”阶段发生异常.System.ComponentModel.Win32Exception:远程过程调用失败 附上提示信息C:\Windows\Microsoft.NET\Framework\v4 ...
- MSSQLSERVER服务不能启动
自从用上mysql,好久没打开sqlserver了,今天本想打开调试下MFC连接sqlserver,然后意外发现不能登录,之后我以为是sql服务没启动,然后去启动,还是没用,并且MSSQLSERVER ...
- python中的generator, iterator, iterabel
先来看看如果遇到一个对象,如何判断其是否是这三种类型: from types import GeneratorType from collectiuons import Iterable, Itera ...
- html.ex.day02
1.同一个目录内页面跳转 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...
- Android开发手记(15) 拨打电话和收发短信
1.Intent简介 Android组价之间的通信,由Intent来协助完成.Intent负责对应用中一次操作的动作.动作涉及数据.附加数据进行描述,Android则根据此Intent的描述,负责找到 ...
- js监听滚动条事件
(function () { if(document.addEventListener){ document.addEventListener('mousewheel',scrollFunc,fals ...
- Hibernate 性能优化之懒加载
针对数据库中的大数据,不希望特别早的加载到内存中,当用到它的时候才加载 懒加载分为:类的懒加载.集合的懒加载.单端关联的懒加载 类的懒加载 1.在默认情况下,类就是执行懒加载 2. ...