【BZOJ2400】Spoj 839 Optimal Marks

Description

定义无向图中的一条边的值为:这条边连接的两个点的值的异或值。
定义一个无向图的值为:这个无向图所有边的值的和。
给你一个有n个结点m条边的无向图。其中的一些点的值是给定的,而其余的点的值由你决定(但要求均为非负数),使得这个无向图的值最小。在无向图的值最小的前提下,使得无向图中所有点的值的和最小。

Input

第一行,两个数n,m,表示图的点数和边数。
接下来n行,每行一个数,按编号给出每个点的值(若为负数则表示这个点的值由你决定,值的绝对值大小不超过10^9)。
接下来m行,每行二个数a,b,表示编号为a与b的两点间连一条边。(保证无重边与自环。)

Output

    第一行,一个数,表示无向图的值。
    第二行,一个数,表示无向图中所有点的值的和。

Sample Input

3 2
2
-1
0
1 2
2 3

Sample Output

2
2

HINT

数据约定
  n<=500,m<=2000
样例解释
    2结点的值定为0即可。

题解:先拆位,然后每个数要么是0要么是1,这显然就转换成了一个最小割问题。

只考虑所有-1的点i,从S->i连一条边代表i有多少1与i相连,从i->T连一条边代表有多少0与i相连,从i->j连一条边代表i,j不同所付出的代价。

但是要求点权和最小怎么办?将边权*10000+点权即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
int n,m,ans,S,T,cnt;
ll ans1,ans2;
int pa[2010],pb[2010],v[510],d[510],head[510],next[10010],val[10010],to[10010],s1[510],s2[510];
queue<int> q;
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,val[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
}
int dfs(int x,int mf)
{
if(x==T) return mf;
int i,k,temp=mf;
for(i=head[x];i!=-1;i=next[i])
{
if(d[to[i]]==d[x]+1&&val[i])
{
k=dfs(to[i],min(temp,val[i]));
if(!k) d[to[i]]=0;
val[i]-=k,val[i^1]+=k,temp-=k;
if(!temp) break;
}
}
return mf-temp;
}
int bfs()
{
memset(d,0,sizeof(d));
while(!q.empty()) q.pop();
int i,u;
q.push(S),d[S]=1;
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=next[i])
{
if(!d[to[i]]&&val[i])
{
d[to[i]]=d[u]+1;
if(to[i]==T) return 1;
q.push(to[i]);
}
}
}
return 0;
}
void work(int x)
{
int i;
S=0,T=n+1;
memset(head,-1,sizeof(head)),cnt=ans=0;
memset(s1,0,sizeof(s1)),memset(s2,0,sizeof(s2));
for(i=1;i<=n;i++)
{
if(v[i]>=0) ans2+=(v[i]&x);
else s2[i]=1;
}
for(i=1;i<=m;i++)
{
if(v[pa[i]]>=0)
{
ans1+=((v[pa[i]]&x)^(v[pb[i]]&x));
}
else if(v[pb[i]]>=0)
{
if(v[pb[i]]&x) s1[pa[i]]+=10000;
else s2[pa[i]]+=10000;
}
else add(pa[i],pb[i],10000),add(pb[i],pa[i],10000);
}
for(i=1;i<=n;i++) if(v[i]<0) add(S,i,s1[i]),add(i,T,s2[i]);
while(bfs()) ans+=dfs(S,1<<30);
ans1+=(ll)x*(ans/10000),ans2+=(ll)x*(ans%10000);
}
int main()
{
n=rd(),m=rd();
int i;
for(i=1;i<=n;i++) v[i]=rd();
for(i=1;i<=m;i++)
{
pa[i]=rd(),pb[i]=rd();
if(v[pa[i]]>v[pb[i]]) swap(pa[i],pb[i]);
}
for(i=0;i<=30;i++) work(1<<i);
printf("%lld\n%lld",ans1,ans2);
return 0;
}
//3 2 3 -1 2 1 2 2 3

【BZOJ2400】Spoj 839 Optimal Marks 最小割的更多相关文章

  1. BZOJ2400: Spoj 839 Optimal Marks

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

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

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

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

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

  4. spoj 839 Optimal Marks(二进制位,最小割)

    [题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17875 [题意] 给定一个图,图的权定义为边的两端点相抑或值的 ...

  5. SPOJ 839 Optimal Marks(最小割的应用)

    https://vjudge.net/problem/SPOJ-OPTM 题意: 给出一个无向图G,每个点 v 以一个有界非负整数 lv 作为标号,每条边e=(u,v)的权w定义为该边的两个端点的标号 ...

  6. BZOJ 2400: Spoj 839 Optimal Marks (按位最小割)

    题面 一个无向图,一些点有固定权值,另外的点权值由你来定. 边的值为两点的异或值,一个无向图的值定义为所有边的值之和. 求无向图的最小值 分析 每一位都互不干扰,按位处理. 用最小割算最小值 保留原图 ...

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

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

  8. 839. Optimal Marks - SPOJ

    You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range ...

  9. 图论(网络流):SPOJ OPTM - Optimal Marks

    OPTM - Optimal Marks You are given an undirected graph G(V, E). Each vertex has a mark which is an i ...

随机推荐

  1. 谷歌Chrome 27测试版已经发布 更快的浏览速度

    谷歌已经发布了Chrome 27测试版浏览器,为普通用户带来了大约提升为5%的网页浏览速度.用户已经可以在Chrome测试网页下载到最新的更新了.我们已经对这版更新做了一个全面的快速测试,让我们看看究 ...

  2. Unity中LoadLevel与LoadLevelAsync的区别

    1.LoadLevel 同步加载 写法:Application.LoadLevel(“name”); 优点:读取场景使用同步的方法就可以,因为是同步方法所以读取的速度是最快的,也不用更新界面,因为同步 ...

  3. gcc 编译时 库链接

    gcc -l参数和-L参数 -l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把 ...

  4. CMake安装或CMake Error at CMakeLists

    CMake安装或CMake Error at CMakeLists 发生情景: 使用cmake命令安装软件时,报如下错误: CMake Error at CMakeLists.txt:4 (CMAKE ...

  5. Day 21 三元表达式、生成器函数、列表解析

    知识点程序: #! /usr/bin/env python # -*- coding: utf-8 -*- # __author__ = "DaChao" # Date: 2017 ...

  6. react 生命周期详解

    state有时候很不听话,在某些时候,我不想他渲染,偏偏react非常智能的帮我们重复渲染. 比如最常见的就是传递的对象为空,组件依旧渲染了一次或者多次. 更多场景不举例了,对症下药. shouldC ...

  7. TCP server和client

    http://blog.csdn.net/hguisu/article/details/7445768/ 原文:http://www.cnblogs.com/dolphinX/p/3460545.ht ...

  8. 证书锁定Certificate Pinning技术

    证书锁定Certificate Pinning技术   在中间人攻击中,攻击主机通常截断客户端和服务器的加密通信.攻击机以自己的证书替代服务器发给客户端的证书.通常,客户端不会验证该证书,直接接受该证 ...

  9. PageHelper分页工具

    <a>共${page.total}件商品</a>    <a>共${page.pages}页</a>    <a>当前第${page.pag ...

  10. java数据库连接池简单实现

    package cn.lmj.utils; import java.io.PrintWriter; import java.lang.reflect.InvocationHandler; import ...