这意味着更复杂的问题,关键的事实被抽象出来:每个点,能够赋予既有的值(挑两个一。需要选择,设定ai,bi)。

寻找所有和最大。有条件:如果两个点同时满足:

1,:二进制只是有一个不同之处。  2:中的至少一个被选择B值。 则可获得相应加成。

这题開始想了半天,建图遇到问题。看了官方说是最小割。于是入手:

a值就是小于阈值的最大值,B值就是大于等于的最大值。

思路:俩个点选其一。必定想到建二分(每一个点一分为二)图。中间连无穷的边。由于仅仅有一位不同,必定分奇偶点,有奇数个1的点,源点到他为A值,相应点到汇点为B值。偶点相反。然后以下奇点向偶点中仅仅有一位不同的点连边,为(ui^uj)。理由:先全部值都取,舍去最小割,便是答案。当都选A值的时候。那么附加的值就不能取了。必是要成为割边,这也是分奇数偶数连发不同的原因,这恰好把同側的关系分到异側了。题目仅仅要方案。不要最值。有负数,先都加2014.  ans=全部权之和-最小割-n*1024。

#include<iostream> //15MS
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
int n,m,nn,mm,ss,tt;
const int inf=0x3f3f3f3f;
const int maxn=1025,maxe=780000;
int rge[maxn];int ui[maxn];
int a[maxn][maxn];
struct xy
{
int low,high;
};
xy dian[maxn];
int head[maxn];int nume=0;int e[maxe][3];
void inline adde(int i,int j,int w)
{
e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
e[nume++][2]=w;
e[nume][0]=i;e[nume][1]=head[j];head[j]=nume;
e[nume++][2]=0;
}
int has1(int i)
{
int ant=0;
while(i)
{
if(i&1)ant++;
i=(i>>1);
}
return ant;
}
void build()
{
for(int i=0;i<nn;i++)
{
adde(i+1,i+nn+1,inf);
if(has1(i)&1)
{
if(dian[i].low!=-1)
adde(ss,i+1,a[i][dian[i].low]);
else
{
adde(ss,i+1,0);
}
adde(i+nn+1,tt,a[i][dian[i].high]);
for(int j=0;j<nn;j++)
{
if(has1(j^i)==1)
{
adde(i+1,1+j+nn,ui[i]^ui[j]);
}
}
}
else
{
if(dian[i].low!=-1)
adde(i+nn+1,tt,a[i][dian[i].low]);
else
{
adde(i+nn+1,tt,0);
}
adde(ss,i+1,a[i][dian[i].high]);
}
}
}
int vis[maxn];int lev[maxn];
bool bfs()
{
for(int i=0;i<tt+2;i++)
lev[i]=vis[i]=0;
queue<int>q;
q.push(ss);
vis[ss]=1;
while(!q.empty())
{
int cur=q.front();
q.pop();
for(int j=head[cur];j!=-1;j=e[j][1])
{
int v=e[j][0];
if(!vis[v]&&e[j][2]>0)
{
vis[v]=1;
lev[v]=lev[cur]+1;
q.push(v);
}
}
}
return vis[tt];
}
int dfs(int cur,int minf)
{
if(cur==tt||minf==0)return minf;
int sumf=0,f;
for(int j=head[cur];j!=-1&&minf;j=e[j][1])
{
int v=e[j][0];
if(lev[v]==lev[cur]+1&&e[j][2]>0)
{
f=dfs(v,e[j][2]<minf? e[j][2]:minf);
minf-=f;sumf+=f;
e[j][2]-=f;e[j^1][2]+=f;
}
}
if(!sumf) lev[cur]=-1;
return sumf;
}
int dinic()
{
int sums=0;
while(bfs())
{
sums+=dfs(ss,inf);
}
return sums;
}
void init()
{
scanf("%d%d",&n,&m);
nn=(1<<n),mm=(1<<m);
ss=0,tt=2*nn+1;
for(int i=0;i<=tt+1;i++)
{
head[i]=-1;
}
nume=0;
for(int i=0;i<nn;i++)
scanf("%d",&rge[i]);
for(int i=0;i<nn;i++)
scanf("%d",&ui[i]);
for(int i=0;i<nn;i++)
for(int j=0;j<mm;j++)
{
scanf("%d",&a[i][j]);
a[i][j]+=1024;
}
for(int i=0;i<nn;i++)
{
dian[i].low=-1;
int max1=0,max2=0;
for(int j=0;j<rge[i];j++)
{
if(a[i][j]>max1){max1=a[i][j];dian[i].low=j;}
}
for(int j=rge[i];j<mm;j++)
{
if(a[i][j]>max2){max2=a[i][j];dian[i].high=j;}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
build();
dinic();
for(int i=1;i<nn;i++)
if(vis[i]&&(has1(i-1)&1)||!vis[i]&&!(has1(i-1)&1))
printf("%d ",dian[i-1].low);
else
printf("%d ",dian[i-1].high);
if(vis[nn]&&(has1(nn-1)&1)||!vis[nn]&&!(has1(nn-1)&1))
printf("%d\n",dian[nn-1].low);
else printf("%d\n",dian[nn-1].high);
}
return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

hdu 5076 最小割灵活运用的更多相关文章

  1. hdu 4289(最小割)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289 思路:求最小花费,最小割应用,将点权转化为边权,拆点,(i,i+n)之间连边,容量为在城市i的花 ...

  2. Game HDU - 3657(最小割)

    Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. hdu 1565 最小割

    黑白染色,源指向白,黑指向汇,容量都是方格中数的大小,相邻的格子白指向黑,容量为oo,然后求一次最小割. 这个割是一个简单割,如果只选择不在割中的点,那么一种割就和一个选数方案一一对应,割的大小就是不 ...

  4. hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割

    题意:方格取数,如果取了相邻的数,那么要付出一定代价.(代价为2*(X&Y))(开始用费用流,敲升级版3820,跪...) 建图:  对于相邻问题,经典方法:奇偶建立二分图.对于相邻两点连边2 ...

  5. Being a Hero (hdu 3251 最小割 好题)

    Being a Hero Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  6. hdu 3657 最小割(牛逼!!!!)总算理解了

    <strong></strong> 转载:http://blog.csdn.net/me4546/article/details/6662959 加颜色的太棒了!!! 在网上看 ...

  7. hdu 3691最小割将一个图分成两部分

    转载地址:http://blog.csdn.net/xdu_truth/article/details/8104721 题意:题给出一个无向图和一个源点,让你求从这个点出发到某个点最大流的最小值.由最 ...

  8. [HDU 3521] [最小割] Being a Hero

    题意: 在一个有向图中,有n个点,m条边$n \le 1000 \And \And  m \le 100000$ 每条边有一个破坏的花费,有些点可以被选择并获得对应的金币. 假设一个可以选的点是$x$ ...

  9. hdu 1569 最小割

    和HDU 1565是一道题,只是数据加强了,貌似轮廓线DP来不了了. #include <cstdio> #include <cstring> #include <que ...

随机推荐

  1. IT痴汉的工作现状13-吓唬电话

    那是一个普通的周末上午,稍微阴沉的天,使得暑气消退了好多.刚吃过早饭,我懒懒的浏览着CSDN论坛上有趣的问题和答案. 突然电话响起.是一个陌生的号码.我像往常一样接起电话,""您好 ...

  2. Windows Phone开发(28):隔离存储B

    原文:Windows Phone开发(28):隔离存储B 上一节我们聊了目录的操作,这一节我们继续来看看如何读写文件. 首先说一下题外话,许多朋友都在摇摆不定,三心二意,其实这样的学习态度是很不好的, ...

  3. [置顶] ffmpg简介以及用它实现音频视频合并(java)

    1.简介     FFmpeg是一个自由软件,可以运行音频和视频多种格式的录影.转档.流功能. 2.下载     源代码 git://git.libav.org/libav.git     Windo ...

  4. arcmap坐标点生成线和面(更正版)

    一:本博客的脉络 (1 )做了例如以下更正:之前在网上搜到的结果是:arcmap坐标点生成线和面 ------ 注意该功能在ArcGIS10中没有了,当时自己也没有多想就转载了,再此做一下更正或者叫做 ...

  5. 【iOS开发-60】案例学习:多组数据的tableView设置、添加右側组索引、多层数据模型设置以及valueForKeyPath

    效果: 这里的数据模型有两层:每一组汽车是一层模型,每一组里面的每一行汽车品牌也是一层模型. (1)我们先创建一个WSCars模型. 在WSCars.h中: #import <Foundatio ...

  6. 玩转Web之servlet(五)---- 怎样解决servlet的线程安全问题

    servlet默认是存在线程安全问题的,但是说白了,servlet的线程安全问题实际上就是多线程的线程安全问题,因为servlet恰巧是一个多线程才会出现安全性问题. 浏览器每次通过http协议去提交 ...

  7. freemarker里的分页--ftl文件的传值

    在上一篇<freemarker里的分页--ftl文件>中我们讨论了分页的逻辑,在这一篇文章中,我们開始看一下怎样进行ftl的传值 或许你在上一篇文章中已经发现了端倪.是的,不错,我们须要一 ...

  8. CopyOnWriteArrayList源代码阅读器

    java.util.concurrent在相应的并发集合的包中定义的通用集合类,为了有效地处理并发场景.间CopyOnWriteArrayList它是合适ArrayList.顾名思义CopyOnWri ...

  9. oracle 选择最频繁出现之前,5文章数据

    SELECT * FROM ( SELECT PROJECT_LISTING.MATERIAL, COUNT (*) AS "出现次数" FROM PROJECT_LISTING ...

  10. SSh框架结构(Struts2.1+Hibernate4.0+Spring3.1)

    一个.使用的工具 开发工具:My Eclipse 10.7以及对应的java开发工具 框架版本号:Struts2.1+Hibernate3+Spring3.0 数据库:MySql5.5 Mysql可视 ...