题面

一个无向图,一些点有固定权值,另外的点权值由你来定.

边的值为两点的异或值,一个无向图的值定义为所有边的值之和.

求无向图的最小值

分析

每一位都互不干扰,按位处理.

用最小割算最小值

  • 保留原图的边,容量为1
  • 如果当前点这一位是1,就从S连向当前点,容量为∞\infty∞
  • 如果当前点这一位是0,就从当前点连向T,容量为∞\infty∞

    那么这样一来,分在S一边就表示选,分在T一边就表示不选.如果相邻的两点在不同的集合,中间的边就必须断掉,造成1的代价,那么刚好相当于中间的边的值.

跑一遍最小割然后从S开始搜,不搜满流的边(也就是被割开的边),加上答案即可

  • 对于在边值相等的情况下,要求点值最小的正确性如下:

    在我们的最小割中,被划分在S一边表示选,那么一条增广路径上有多条满流边的时候,我们的搜索处理方法是遇到满流边就不往下走.所以我们割的边一定最靠近S集,也就是尽量地多让剩下点被分在T集(也就是选0),这样就满足了在同等情况下尽量选0使得点值最小.
  • 另一种方法是把边值设为10000,点值设为1.那么最小边值之和就是ans/10000,在此情况下的最小点值就是ans%10000

CODE

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
template<typename T>inline void read(T &num) {
char ch; int flg=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flg=-flg;
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
num*=flg;
}
const int inf = 1e9;
const int MAXN = 505;
const int MAXM = 20005;
int n, m, fir[MAXN], S, T, cnt;
struct edge { int to, nxt; LL c; }e[MAXM];
inline void add(int u, int v, LL cc, LL rc=0) {
e[cnt] = (edge){ v, fir[u], cc }; fir[u] = cnt++;
e[cnt] = (edge){ u, fir[v], rc }; fir[v] = cnt++;
}
int dis[MAXN], vis[MAXN], info[MAXN], cur, q[MAXN];
inline bool bfs() {
int head = 0, tail = 0;
vis[S] = ++cur; q[tail++] = S;
while(head < tail) {
int u = q[head++];
for(int i = fir[u]; ~i; i = e[i].nxt)
if(e[i].c && vis[e[i].to] != cur)
vis[e[i].to] = cur, dis[e[i].to] = dis[u] + 1, q[tail++] = e[i].to;
}
if(vis[T] == cur) memcpy(info, fir, (T+1)<<2);
return vis[T] == cur;
}
LL dfs(int u, LL Max) {
if(u == T || !Max) return Max;
LL flow=0, delta;
for(int &i = info[u]; ~i; i = e[i].nxt)
if(e[i].c && dis[e[i].to] == dis[u] + 1 && (delta=dfs(e[i].to, min(e[i].c, Max-flow)))) {
e[i].c -= delta, e[i^1].c += delta, flow += delta;
if(flow == Max) return flow;
}
return flow;
}
inline LL dinic() {
memset(vis, 0, sizeof vis);
LL flow=0, x;
while(bfs()) {
while((x=dfs(S, inf))) flow+=x;
}
return flow;
}
int A[MAXN], X[2005], Y[2005]; LL ans1, ans2;
bool flg[MAXN];
void Getans2(int u, int val) {
if(u) ans2 += val; flg[u] = 1;
for(int i = fir[u]; ~i; i = e[i].nxt)
if(e[i].c && !flg[e[i].to])
Getans2(e[i].to, val);
}
int main () {
read(n); read(m); S = 0, T = n+1;
for(int i = 1; i <= n; ++i) read(A[i]);
for(int i = 1; i <= m; ++i) read(X[i]), read(Y[i]);
for(int bit = 0; bit < 30; ++bit) {
memset(fir, -1, sizeof fir); cnt = 0;
for(int i = 1; i <= m; ++i) add(X[i], Y[i], 1, 1);
for(int i = 1; i <= n; ++i) {
if(A[i] < 0) continue;
if(A[i]&(1<<bit)) add(S, i, inf);
else add(i, T, inf);
}
memset(flg, 0, sizeof flg);
ans1 += dinic() * (1<<bit);
Getans2(S, 1<<bit);
}
printf("%lld\n%lld\n", ans1, ans2);
}

Upd:Upd:Upd:不开long longlong\ longlong long毁一生

BZOJ 2400: Spoj 839 Optimal Marks (按位最小割)的更多相关文章

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

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

  2. Luogu SP839 OPTM - Optimal Marks(按位最小割)

    这道题和 BZOJ 2400 是一道题,不多讲了 CODE #include <cstdio> #include <cstring> #include <vector&g ...

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

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

  4. BZOJ2400: Spoj 839 Optimal Marks

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

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

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

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

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

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

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

  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. Redis 5.0.5 Install manual

    Redis 5.0.5 安装文档(Install manual) 一.单实例安装 标题 内容 测试环境 Centos 7 虚拟机 vbox redis版本 redis 5.0.5 1.编译安装redi ...

  2. 为什么 Python 中的 True 等于 1

    开始的时候,需要用以下函数来做一个判断,根据返回的值来做一些后续判断处理: def is_success(param): if not param: return False return True ...

  3. Mysql主从复制原理及同步延迟问题

    本文转载自:Mysql主从复制原理及同步延迟问题 主从复制解决的问题 数据分布:通过复制将数据分布到不同地理位置 负载均衡:读写分离以及将读负载到多台从库 备份:可作为实时备份 高可用性:利用主主复制 ...

  4. 方法区(关于java虚拟机内存的那些事)

    <深入理解 java 虚拟机> 读书扩展 作者:淮左白衣 写于 2018年4月13日21:26:05 目录 方法区 图例(方法区中都保存什么) 类型信息 类型的常量池 (即运行时常量池) ...

  5. c# asp.net 实现分页(pager)功能

    分页PagerHelper辅助类 using System;using System.Web; public class PagerHelper { #region 获取分页的Html代码 /// & ...

  6. popcorn-js视频Video框架简单用法

    <div> <video class="video" id="ourvideobig" preload="auto" co ...

  7. ngix介绍

    ngix能做什么?  1 反向代理 2 负载均衡 3 正向代理 4 HTTP服务器(动静分离) 1 反向代理 Reverse Proxy 是指以代理服务器来接受来自internet或者是客户端的连接请 ...

  8. 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Coin 矩阵快速幂

    Bob has a not even coin, every time he tosses the coin, the probability that the coin's front face u ...

  9. K2 BPM_【解决方案】从流程梳理到落地,K2为企业打造流程管理闭环_全业务流程管理专家

    很多企业在进行流程管理体系建设的过程中,往往急于求成,还没有理清楚要“做什么”和“怎么做”,就开始大刀阔斧地进行改革优化.管理目标.建设标准的不统一,使得体系建设之间内容重复.要求冲突等现象层出不穷. ...

  10. 【数字图像处理】帧差法与Kirsch边缘检测实现运动目标识别与分割

    本文链接:https://blog.csdn.net/qq_18234121/article/details/82763385 作者:冻人的蓝鲸梁思成 视频分割算法可以从时域和空域两个角度考虑.时域分 ...