传送门

论文《最小割模型在信息学竞赛中的应用》原题

二进制不同位上互不影响,那么就按位跑网络流

每一位上,确定的点值为1的与S连一条容量为INF的有向边。为0的与T连一条容量为INF的有向边。

其他的按给定的无向图建边,容量为1。

统计答案是从源点能到达的点(流量未达到容量)即为该位上为1的点。

需要跑多少遍根据所有权值的最高位来确定。直接跑30次TLE了。

#include <bits/stdc++.h>
using namespace std; inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} const int INF = 0x3f3f3f3f;
const int N = 2e5 + ;
struct Edge { int v, next, f; } edge[N];
struct IN { int u, v; } in[N];
int head[N], cnt, level[N], iter[N], n, m;
int a[N], res[N];
bool vis[N];
vector<int> appear; inline void add(int u, int v, int f) {
edge[cnt].v = v; edge[cnt].f = f; edge[cnt].next = head[u]; head[u] = cnt++;
} bool bfs(int s, int t) {
for (int i = ; i <= t; i++) level[i] = -, iter[i] = head[i];
queue<int> que;
que.push(s);
level[s] = ;
while (!que.empty()) {
int u = que.front(); que.pop();
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v, f = edge[i].f;
if (level[v] < && f) {
que.push(v);
level[v] = level[u] + ;
}
}
}
return level[t] != -;
} int dfs(int u, int t, int f) {
if (u == t || !f) return f;
int flow = ;
for (int i = iter[u]; ~i; i = edge[i].next) {
iter[u] = i;
int v = edge[i].v;
if (level[v] == level[u] + && edge[i].f) {
int w = dfs(v, t, min(f, edge[i].f));
if (!w) continue;
flow += w; f -= w;
edge[i].f -= w; edge[i^].f += w;
if (f <= ) break;
}
}
return flow;
} int dinic(int s, int t) {
int ans = ;
while (bfs(s, t)) ans += dfs(s, t, INF);
return ans;
} void get_ans(int u, int bit) {
vis[u] = ;
res[u] += << bit;
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if (!vis[v] && edge[i].f) {
get_ans(v, bit);
}
}
} void solve(int bit, int s, int t) {
for (int i = ; i <= t; i++) head[i] = -, vis[i] = false;
cnt = ;
for (int i = , sz = appear.size(); i < sz; i++) {
int x = appear[i];
if (( << bit) & a[x]) {
add(s, x, INF);
add(x, s, );
} else {
add(x, t, INF);
add(t, x, );
}
}
for (int i = ; i <= m; i++) { add(in[i].u, in[i].v, ); add(in[i].v, in[i].u, ); }
dinic(s, t);
get_ans(s, bit);
} inline void init() {
for (int i = ; i <= n; i++) {
res[i] = a[i] = ;
}
appear.clear();
} int main() {
int T = read();
while (T--) {
n = read(), m = read();
init();
int s = , t = n + ;
int mak = ;
for (int i = ; i <= m; i++) {
in[i].u = read(), in[i].v = read();
}
int k = read();
while (k--) {
int u = read();
a[u] = read();
appear.emplace_back(u);
}
for (int i = , sz = appear.size(); i < sz; i++) {
int u = appear[i];
int temp = a[u];
int bit = ;
while (temp) {
bit++;
temp >>= ;
}
mak = max(bit, mak);
}
for (int i = ; i <= mak; i++) {
solve(i, s, t);
}
for (int i = ; i <= n; i++) printf("%d\n", res[i]);
}
}

Optimal Marks SPOJ - OPTM(最小割)的更多相关文章

  1. Optimal Marks SPOJ - OPTM (按位枚举-最小割)

    题意:给一张无向图,每个点有其点权,边(i,j)的cost是\(val_i\ XOR \ val_j\).现在只给出K个点的权值,求如何安排其余的点,使总花费最小. 分析:题目保证权值不超过32位整型 ...

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

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

  3. Optimal Marks SPOJ - OPTM

    传送门 一个无向图,每个点有点权,某些点点权确定了,某些点由你来确定,边权为两个点的异或和,要使边权和最小. 这不是一道按位做最小割的大水题么 非常开心地打了,还非常开心地以为有spj,然后非常开心地 ...

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

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

  5. 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 ...

  6. Optimal Marks SPOJ 839

    这题远超其他题非常靠近最小割的实际意义: 割边<=>付出代价<=>决定让两个点的值不相同,边权增加 最小割<=>点的值与s一个阵营的与s相同,与t一个阵营的与t相同 ...

  7. spoj 839 最小割+二进制

    #include<stdio.h> #include<string.h> #include<queue> using namespace std; #define ...

  8. SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)

    http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...

  9. spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】

    因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...

随机推荐

  1. Django框架之第三篇(路由层)--有名/无名分组、反向解析、路由分发、名称空间、伪静态

    一.Django请求生命周期 二.路由层  urls.py url()方法 第一个参数其实就是一个正则表达式,一旦前面的正则匹配到了内容,就不会再往下继续匹配,而是直接执行对应的视图函数. djang ...

  2. Go基础编程实践(三)—— 日期和时间

    日期和时间 package main import ( "fmt" "time" ) func main() { // 获取当前时间 current := ti ...

  3. 关于一致性hash,这可能是全网最形象生动最容易理解的文档,想做架构师的你来了解一下

    问题提出 一致性hash是什么?假设有4台缓存服务器N0,N1,N2,N3,现在需要存储数据OBJECT1,OBJECT2,OBJECT3,OBJECT4,OBJECT5,OBJECT5,OBJECT ...

  4. 【LEETCODE】61、对leetcode的想法&数组分类,适中级别,题目:162、73

    这几天一直再想这样刷题真的有必要么,这种单纯的刷题刷得到尽头么??? 这种出题的的题目是无限的随便百度,要多少题有多少题,那么我这一直刷的意义在哪里??? 最近一直苦苦思考,不明所以,刷题刷得更多的感 ...

  5. SSM整合学习 四

    事务管理 一:初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个 ...

  6. windows中端口查看&关闭进程

    在一些情况下遇到的端口占用问题解决: 1.查看端口占用情况 命令:netstat -ano 命令:netstat -ano | findstr 需要释放的端口号 2.查看某端口的占用进程 命令:tas ...

  7. ubuntu 安装Jenkins

    一.介绍 Jenkins是一款开源自动化服务器,旨在自动化连续集成和交付软件所涉及的重复技术任务. Jenkins是基于Java的,可以从Ubuntu软件包安装,也可以通过下载和运行其Web应用程序A ...

  8. Golang ---基准测试

    什么是基准测试 基准测试,是一种测试代码性能的方法,比如你有多种不同的方案,都可以解决问题,那么到底是那种方案性能更好呢?这时候基准测试就派上用场了. 基准测试主要是通过测试CPU和内存的效率问题,来 ...

  9. mysql 查询导出 excel 中文乱码 解决 --default-character-set=gbk

    mysql  --default-character-set=gbk -uroot -p   -D open_fusion -e  " select * from table1  " ...

  10. RabbitMQ Policy的使用

    RabbitMQ作为最流行的MQ中间件之一,广泛使用在各类系统中,今天我们就来讨论一下如何通过Policies给RabbitMQ中已经创建的Queue添加属性和参数. Policise 的作用 通常来 ...