Optimal Marks SPOJ - OPTM(最小割)
论文《最小割模型在信息学竞赛中的应用》原题
二进制不同位上互不影响,那么就按位跑网络流
每一位上,确定的点值为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(最小割)的更多相关文章
- Optimal Marks SPOJ - OPTM (按位枚举-最小割)
题意:给一张无向图,每个点有其点权,边(i,j)的cost是\(val_i\ XOR \ val_j\).现在只给出K个点的权值,求如何安排其余的点,使总花费最小. 分析:题目保证权值不超过32位整型 ...
- BZOJ 2400: Spoj 839 Optimal Marks (按位最小割)
题面 一个无向图,一些点有固定权值,另外的点权值由你来定. 边的值为两点的异或值,一个无向图的值定义为所有边的值之和. 求无向图的最小值 分析 每一位都互不干扰,按位处理. 用最小割算最小值 保留原图 ...
- Optimal Marks SPOJ - OPTM
传送门 一个无向图,每个点有点权,某些点点权确定了,某些点由你来确定,边权为两个点的异或和,要使边权和最小. 这不是一道按位做最小割的大水题么 非常开心地打了,还非常开心地以为有spj,然后非常开心地 ...
- Luogu SP839 OPTM - Optimal Marks(按位最小割)
这道题和 BZOJ 2400 是一道题,不多讲了 CODE #include <cstdio> #include <cstring> #include <vector&g ...
- 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 ...
- Optimal Marks SPOJ 839
这题远超其他题非常靠近最小割的实际意义: 割边<=>付出代价<=>决定让两个点的值不相同,边权增加 最小割<=>点的值与s一个阵营的与s相同,与t一个阵营的与t相同 ...
- spoj 839 最小割+二进制
#include<stdio.h> #include<string.h> #include<queue> using namespace std; #define ...
- SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)
http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...
- spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】
因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...
随机推荐
- 【LEETCODE】72、分割回文串 III 第1278题
package y2019.Algorithm.dynamicprogramming.hard; /** * @Auther: xiaof * @Date: 2019/12/11 08:59 * @D ...
- PV、UV、UIP、VV、DAU、CTR指的是什么?
PV(page view) 网站浏览量,指网页的浏览次数,用户每打开一次页面就记录一次PV,多次打开则累加. UV(unique vistor) 独立访客数,指的是某一天访问某站点的人数,以cooki ...
- AX 2012 Computed column IIF语句使用
涉及Dynamics ax 行业已经好几年了,准备总结一些有用的处理方法供大家来参考 首先先介绍下Computed column技术,该技术是微软在AX2012版本中提供的新技术,可以让SQL语句在A ...
- Python-记事本
1.文本颜色 格式:\[显示方式;前景色;背景色m要打印的字符串\[0m 2.format 格式 print('{}的三次方为{:*^20}'.format(a,pow(a, 3))) print(& ...
- Python进阶(九)----json模块, pickle模块, os模块,sys模块,hashlib模块
Python进阶----json模块, pickle模块, os模块,sys模块,hashlib模块 一丶序列化模块 什么是序列化: 将一种数据结构,转换成一个特殊的序列(特殊字符串,用于网络传输 ...
- Qt Creator 的下载与安装
一.Qt和Qt Creator的区别 Qt是C++的一个库,或者说是开发框架,里面集成了一些库函数,提高开发效率. Qt Creator是一个IDE,就是一个平台,一个开发环境,类似的比如说VS,也可 ...
- Android选项卡TabHost功能和用法
1.布局文件 <TabHost xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...
- MySQL Percona Toolkit--pt-osc学习
工作流程 1.检查更改表是否有主键或唯一索引,是否有触发器 2.检查修改表的表结构,创建一个临时表,在新表上执行ALTER TABLE语句 3.在源表上创建三个触发器分别对于INSERT UPDATE ...
- Oracle UNDO块
过程:开始一个事务--通过事务信息找到UNDO块头的所在的段名及数据文件号等--转储UNDO header--在事务表中对应槽位找到前镜像dba--转储数据块--找到对应记录得到bdba--转储数据块 ...
- Spring— 用更优雅的方式发HTTP请求(RestTemplate详解)
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率. 我之前的HTTP开发是用ap ...