[SPOJ839]Optimal Marks
[SPOJ839]Optimal Marks
试题描述
You are given an undirected graph \(G(V, E)\). Each vertex has a mark which is an integer from the range \([0..2^{31} - 1]\). Different vertexes may have the same mark.
For an edge \((u, v)\), we define \(Cost(u, v) = mark[u] xor mark[v]\).
Now we know the marks of some certain nodes. You have to determine the marks of other nodes so that the total cost of edges is as small as possible.
给你一个无向图,有些点权值固定,你需要个剩下的点确定权值使得所有边的权值之和最小。边权定义为它连接的两个点的点权异或。
输入
The first line of the input data contains integer \(T\) \((1 \le T \le 10)\) - the number of testcases. Then the descriptions of \(T\) testcases follow.
First line of each testcase contains \(2\) integers \(N\) and \(M\) \((0 < N \le 500, 0 \le M \le 3000)\). \(N\) is the number of vertexes and \(M\) is the number of edges. Then \(M\) lines describing edges follow, each of them contains two integers \(u, v\) representing an edge connecting \(u\) and \(v\).
Then an integer \(K\), representing the number of nodes whose mark is known. The next \(K\) lines contain \(2\) integers \(u\) and \(p\) each, meaning that node \(u\) has a mark \(p\). It’s guaranteed that nodes won’t duplicate in this part.
输出
For each testcase you should print \(N\) lines integer the output. The \(K\)th line contains an integer number representing the mark of node \(K\). If there are several solutions, you have to output the one which minimize the sum of marks. If there are several solutions, just output any of them.
输入示例
1
3 2
1 2
2 3
2
1 5
3 100
输出示例
5
4
100
数据规模及约定
见“输入”
题解
异或、求和,每一位都互不影响,套路做法就是按位处理。
对于某一位,每个点的点权只有 \(0/1\) 两种情况,自然想到 \(0\) 的点属于 \(S\) 割,\(1\) 的点属于 \(T\) 割,然后把原图复制上去,无向边边权为 \(1\),跑最小割。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i++)
#define dwn(i, s, t) for(int i = (s); i >= (t); i--)
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
#define maxn 510
#define maxm 7010
#define oo 2147483647
struct Edge {
int from, to, flow;
Edge() {}
Edge(int _1, int _2, int _3): from(_1), to(_2), flow(_3) {}
};
struct Dinic {
int n, m, s, t, head[maxn], nxt[maxm];
Edge es[maxm];
int vis[maxn], Q[maxn], hd, tl;
int cur[maxn];
bool tcut[maxn];
void init() {
m = 0; memset(head, -1, sizeof(head));
return ;
}
void setn(int _) {
n = _;
return ;
}
void AddEdge(int a, int b, int c) {
es[m] = Edge(a, b, c); nxt[m] = head[a]; head[a] = m++;
return ;
}
bool BFS() {
memset(vis, 0, sizeof(vis));
hd = tl = 0; Q[++tl] = t;
vis[t] = 1;
while(hd < tl) {
int u = Q[++hd];
for(int i = head[u]; i != -1; i = nxt[i]) {
Edge& e = es[i^1];
if(!vis[e.from] && e.flow) {
vis[e.from] = vis[u] + 1;
Q[++tl] = e.from;
}
}
}
return vis[s] > 0;
}
int DFS(int u, int a) {
if(u == t || !a) return a;
int flow = 0, f;
for(int& i = cur[u]; i != -1; i = nxt[i]) {
Edge& e = es[i];
if(vis[e.to] == vis[u] - 1 && (f = DFS(e.to, min(a, e.flow)))) {
flow += f; a -= f;
e.flow -= f; es[i^1].flow += f;
if(!a) return flow;
}
}
return flow;
}
int MaxFlow(int _s, int _t) {
s = _s; t = _t;
int flow = 0;
while(BFS()) {
rep(i, 1, n) cur[i] = head[i];
flow += DFS(s, oo);
}
return flow;
}
void dfs(int u) {
if(tcut[u]) return ;
tcut[u] = 1;
for(int i = head[u]; i != -1; i = nxt[i]) {
Edge& e = es[i^1];
if(e.flow) dfs(e.from);
}
return ;
}
} sol;
#define pii pair <int, int>
#define x first
#define y second
#define mp(x, y) make_pair(x, y)
pii es[maxm];
int n, m, val[maxn], getv[maxn];
void solve(int bit) {
int s = n + 1, t = n + 2;
sol.init(); sol.setn(t);
rep(i, 1, m) sol.AddEdge(es[i].x, es[i].y, 1), sol.AddEdge(es[i].y, es[i].x, 1);
rep(i, 1, n) if(val[i] >= 0) {
if(val[i] >> bit & 1) sol.AddEdge(i, t, oo), sol.AddEdge(t, i, 0);
else sol.AddEdge(s, i, oo), sol.AddEdge(i, s, 0);
}
sol.MaxFlow(s, t);
memset(sol.tcut, 0, sizeof(sol.tcut));
sol.dfs(t);
rep(i, 1, n) if(val[i] < 0)
getv[i] |= sol.tcut[i] << bit;
return ;
}
int main() {
int T = read();
while(T--) {
n = read(); m = read();
memset(val, -1, sizeof(val));
rep(i, 1, m) {
int a = read(), b = read();
es[i] = mp(a, b);
}
int k = read();
rep(i, 1, k) {
int t = read();
val[t] = read();
}
memset(getv, 0, sizeof(getv));
rep(i, 0, 31) solve(i);
rep(i, 1, n) if(val[i] >= 0) printf("%d\n", val[i]); else printf("%d\n", getv[i]);
}
return 0;
}
大概这题数据范围有问题,二进制位从 \(0\) 到 \(30\) 就 WA,到 \(31\) 就 A 了。
[SPOJ839]Optimal Marks的更多相关文章
- SPOJ839 Optimal Marks(最小割)
题目大概说给一张图,每个点都有权,边的权等于其两端点权的异或和,现已知几个点的权,为了使所有边的边权和最小,其他点的权值该是多少. 很有意思的一道题,完全看不出和网络流有什么关系. 考虑每个未知的点$ ...
- spoj839 Optimal Marks(最小割,dinic)
题目大意: 给你一个无向图\(G(V,E)\). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记. 对于边\((u,v)\),我们定义\(Cost(u,v)=mark [u]\ ...
- 图论(网络流):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 ...
- SPOJ OPTM - Optimal Marks
OPTM - Optimal Marks no tags You are given an undirected graph G(V, E). Each vertex has a mark whic ...
- SP839 Optimal marks(最小割)
SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...
- Optimal Marks(optimal)
Optimal Marks(optimal) 题目描述 定义无向图边的值为这条边连接的两个点的点权异或值. 定义无向图的值为无向图中所有边的值的和. 给定nn个点mm条边构成的图.其中有些点的权值是给 ...
- 【bzoj2400】Spoj 839 Optimal Marks 按位最大流
Spoj 839 Optimal Marks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 908 Solved: 347[Submit][Stat ...
- 【BZOJ2400】Spoj 839 Optimal Marks 最小割
[BZOJ2400]Spoj 839 Optimal Marks Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...
- SPOJ839 OPTM - Optimal Marks
传送门 闵神讲网络流应用的例题,来水一水 要写出这道题,需要深入理解两个概念,异或和最小割. 异或具有相对独立性,所以我们把每一位拆开来看,即做大概$32$次最小割.然后累加即可. 然后是最小割把一张 ...
随机推荐
- Jquery LigerUI
http://www.ligerui.com/index.aspx http://api.ligerui.com/ 分享一个基于ligerui的系统应用案例ligerRM V2(权限管理系统)(提供下 ...
- C#的接口基础教程之六 接口转换
C#中不仅支持.Net 平台,而且支持COM平台.为了支持 COM和.Net,C# 包含一种称为属性的独特语言特性.一个属性实际上就是一个 C# 类,它通过修饰源代码来提供元信息.属性使 C# 能够支 ...
- display :inline-block 处理点小障碍
使用inline-block之前先处理点小障碍:inline-block元素会有4px左右的空隙,这个是因为我们写代码时候的换行符所致. 解决办法很简单:在inline-block的父元素中设置样式f ...
- SAP 各模块常用的BAPI
MM模块 1. BAPI_MATERIAL_SAVEDATA 创建物料主数据 注意参数EXTENSIONIN的使用,可以创建自定义字段 例如:WA_BAPI_TE_MARA-MATERIAL = IT ...
- Java读取各种文件格式内容
所需的jar包哦也不要太记得了,大家可以搜搜,直接上代码: import java.io.BufferedInputStream; import java.io.File; import java.i ...
- JavaScript 日期权威指南
简介 JavaScript通过强大的对象为我们提供日期处理功能:日期. 本文确实_不是_谈论 Moment.js ,我认为它是处理日期的最佳库,你应该在处理日期时几乎总是使用它. Date对象 Dat ...
- LigerUI 快速开发UI框架 链接
LigerUI 快速开发UI框架 http://www.ligerui.com/ jQuery ligerUI 中文官方网站 http://www.ligerui.com/demo.html
- EventUtil处理js兼容性问题
var EventUtil={ addHandler:function(element,type,handler){ //添加事件 if(element.addEventListener){ elem ...
- CentOS6.7下的软件安装
一.JDK安装及其环境变量的配置 **创建一个专门安装软件的文件夹:mkdir /root/apps **解压安装包:tar -zxvf jdk-7u45-linux-x64.tar.gz -C /r ...
- Python3爬取起点中文网阅读量信息,解决文字反爬~~~附源代码
起点中文网,在“数字”上设置了文字反爬,使用了自定义的文字文件ttf通过浏览器的“检查”显示的是“□”,但是可以在网页源代码中找到映射后的数字正则爬的是网页源代码,xpath是默认utf-8解析网页数 ...