首先xor类的题目一定要逐位考虑,因为位位之间是不相互影响的
逐位考虑每个点是0还是1,这就转化成了一个这样一个问题
对于每个点可以选择属于S集合(这位是0)或T集合(这位是1)
某些的点对(一条边的两端)属于不同集合会产生一个附加值1(边权)
现在要是附加值最小(边权当前位为1的边最少),并且属于S集合的尽可能多(点权当前位为1尽可能少)
显然第一个问题是一个最小割的问题,对于已经确定这位是什么的点i来说
是0则连边s-->i 容量inf,是1则连边i-->t容量是inf,因为这些点当前位是确定的
然后对一条边(u,v),连边u-->v v-->u 容量都是1,最小割就是最小附加值
这里为什么不用给不确定的点向s,t连边呢?这个我也没有想清楚
反正直观的感受,当一条路径直接或间接连接着则两点一个确定为0,一个确定为1,
那么这条路径最少会产生附加值1,一定要被割断,否则这条路径我一定能使它不产生附加值
下面考虑让属于S的点(这位是0的点)尽可能多
考虑在残流网络上是不存在增广路的,也就是对于一个未确定点i,如果这个点能属于S
那么我从s到i给一个流量,这个流量从点i一定不能流向t,否则就会增大边权和
因此我们只要对于每个未确定的点i在残流网络上顺着剩余容量大于0的边dfs,
只要到不了t,那么这个点就可以属于S(这位为0),否则不行
这样就解决了

 const inf=;
type node=record
point,next,flow:longint;
end; var edge:array[..] of node;
p,cur,d,a,pre,h,numh:array[..] of longint;
v:array[ ..] of boolean;
x,y:array[..] of longint;
i,j,n,m,k,len,t,b:longint;
ans1,ans2:int64; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; procedure add(x,y,f:longint);
begin
inc(len);
edge[len].point:=y;
edge[len].flow:=f;
edge[len].next:=p[x];
p[x]:=len;
end; function sap:longint;
var u,i,j,tmp,neck,q:longint;
begin
fillchar(h,sizeof(h),);
fillchar(numh,sizeof(numh),);
numh[]:=t+;
u:=;
for i:= to t do
cur[i]:=p[i];
neck:=inf;
sap:=;
while h[]<t+ do
begin
d[u]:=neck;
i:=cur[u];
while i<>- do
begin
j:=edge[i].point;
if (edge[i].flow>) and (h[u]=h[j]+) then
begin
pre[j]:=u;
cur[u]:=i;
neck:=min(neck,edge[i].flow);
u:=j;
if u=t then
begin
sap:=sap+neck;
while u<> do
begin
u:=pre[u];
j:=cur[u];
dec(edge[j].flow,neck);
inc(edge[j xor ].flow,neck);
end;
neck:=inf;
end;
break;
end;
i:=edge[i].next;
end;
if i=- then
begin
dec(numh[h[u]]);
if numh[h[u]]= then exit;
tmp:=t;
q:=-;
i:=p[u];
while i<>- do
begin
j:=edge[i].point;
if edge[i].flow> then
if h[j]<tmp then
begin
tmp:=h[j];
q:=i;
end;
i:=edge[i].next;
end;
h[u]:=tmp+;
cur[u]:=q;
inc(numh[h[u]]);
if u<> then
begin
u:=pre[u];
neck:=d[u];
end;
end;
end;
end; function dfs(x:longint):boolean;
var i,y:longint;
begin
v[x]:=true;
if x=t then exit(true);
i:=p[x];
while i<>- do
begin
y:=edge[i].point;
if (edge[i].flow>) and not v[y] then
if dfs(y) then exit(true);
i:=edge[i].next;
end;
exit(false);
end; begin
readln(n,m);
b:=;
for i:= to n do
begin
readln(a[i]);
if (a[i]>) and (trunc(ln(a[i])/ln())>b) then
b:=trunc(ln(a[i])/ln()); //显然比以确定点的最大位数还大的位直接取0即可
if a[i]> then ans2:=ans2+a[i];
end;
for i:= to m do
readln(x[i],y[i]);
t:=n+;
for i:= to b do
begin
len:=-;
fillchar(p,sizeof(p),);
for j:= to n do
if a[j]>= then
begin
if a[j] and ( shl i)= then
begin
add(,j,inf);
add(j,,);
end
else begin
add(j,t,inf);
add(t,j,);
end;
end;
for j:= to m do
begin
add(x[j],y[j],);
add(y[j],x[j],);
add(y[j],x[j],);
add(x[j],y[j],);
end;
ans1:=ans1+int64(sap)*int64( shl i); // shl i是这位位权
for j:= to n do
if a[j]< then
begin
fillchar(v,sizeof(v),false);
if dfs(j) then ans2:=ans2+ shl i; //能访问到t则这个点当前位不能为0
end;
end;
writeln(ans1);
writeln(ans2);
end.

bzoj2400的更多相关文章

  1. 【BZOJ2400】Spoj 839 Optimal Marks 最小割

    [BZOJ2400]Spoj 839 Optimal Marks Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...

  2. 【BZOJ-2400】Spoj839Optimal Marks 最小割 + DFS

    2400: Spoj 839 Optimal Marks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 567  Solved: 202[Submit ...

  3. BZOJ2400: Spoj 839 Optimal Marks

    Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其 ...

  4. 【bzoj2400】Spoj 839 Optimal Marks 按位最大流

    Spoj 839 Optimal Marks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 908  Solved: 347[Submit][Stat ...

  5. 【bzoj2400】Spoj 839 Optimal Marks 网络流最小割

    题目描述 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其余的点的值由你 ...

  6. 【BZOJ2400】Optimal Marks

    题意 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有 \(n\) 个结点 \(m\) 条边的无向图.其中的一些点的值是给定的 ...

  7. [bzoj2400]Optimal Marks

    首先肯定每一位单独考虑,对于每一位,源点连向该位点权为0的节点inf的边,点权为1的节点连向汇点inf的边,每一条无向边拆成两条流量为1的有向边,跑最小割. 考虑一组割,一定将原图划分成源点和汇点两部 ...

  8. [转载]hzwer的bzoj题单

    counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ120 ...

  9. BZOJ刷题列表【转载于hzwer】

    沿着黄学长的步伐~~ 红色为已刷,黑色为未刷,看我多久能搞完吧... Update on 7.26 :之前咕了好久...(足见博主的flag是多么emmm......)这几天开始会抽时间刷的,每天几道 ...

随机推荐

  1. app 的内存优化

    这篇文章是笔者在开发App过程中发现的一些内存问题, 然后学习了YYKit框架时候也发现了图片的缓存处理 (YYKit 作者联系了我, 说明了YYKit重写imageNamed:的目的不是为了内存管理 ...

  2. PRD产品需求文档概要

    PRD概念 PRM就是Product Requirements Document的简称,也就是产品需求模型.一般来说一个产品会伴随有市场需求文档(Market Requirements Documen ...

  3. Linux squid 安装配置

    linux 代理软件 squid 查看是否安装squid   以上信息表明,本机是已经安装了此软件了 如果没有显示说明没有安装,则可以使用yum工具来安装   安装完软件后我们接着开始配置squid代 ...

  4. 关于一些Android冷知识

    1. 在Android4.0以后,EditText就由以前的输入框变成了一条划线的输入方式,如需要变为老版本的,只需在layout里面引入代码: android:background="@a ...

  5. 01.WPF中制作无边框窗体

    [引用:]http://blog.csdn.net/johnsuna/article/details/1893319   众所周知,在WinForm中,如果要制作一个无边框窗体,可以将窗体的FormB ...

  6. SQL Server死锁日志各字段含义

    使用跟踪标记 1204 --打开跟踪标记 DBCC TRACEON (1204,-1) --关闭跟踪标记 DBCC TRACEOFF (1204,-1) 处于死锁状态时,跟踪标记 1204 在等待的线 ...

  7. weChat聊天发送图片带有小尖角的实现

    weChat聊天发送图片带有小尖角的实现 1.#import <UIKit/UIKit.h>2.3.@interface JKShapeImage : UIView4.5.@propert ...

  8. android查看真机中的数据库

    0.在有网的前提下1.安装 Android Studio,Lantern,Chrome浏览器2.在在githab上搜索stetho,打开第一个facebook/stetho3.在Gradle Scri ...

  9. 344. Reverse String(C++)

    344. Reverse String Write a function that takes a string as input and returns the string reversed. E ...

  10. 最全Media 响应式 设置方法

    大家对于css3中media属性并不陌生,但是随着一些高视网膜的设备面世,很多情况对于media的不标准的用法也越来越多,我通过查找一些知识结合实践给总结出一些标准的设置的方法. CSS3 中的 Me ...