[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的更多相关文章

  1. SPOJ839 Optimal Marks(最小割)

    题目大概说给一张图,每个点都有权,边的权等于其两端点权的异或和,现已知几个点的权,为了使所有边的边权和最小,其他点的权值该是多少. 很有意思的一道题,完全看不出和网络流有什么关系. 考虑每个未知的点$ ...

  2. spoj839 Optimal Marks(最小割,dinic)

    题目大意: 给你一个无向图\(G(V,E)\). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记. 对于边\((u,v)\),我们定义\(Cost(u,v)=mark [u]\ ...

  3. 图论(网络流):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 ...

  4. SPOJ OPTM - Optimal Marks

    OPTM - Optimal Marks no tags  You are given an undirected graph G(V, E). Each vertex has a mark whic ...

  5. SP839 Optimal marks(最小割)

    SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...

  6. Optimal Marks(optimal)

    Optimal Marks(optimal) 题目描述 定义无向图边的值为这条边连接的两个点的点权异或值. 定义无向图的值为无向图中所有边的值的和. 给定nn个点mm条边构成的图.其中有些点的权值是给 ...

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

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

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

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

  9. SPOJ839 OPTM - Optimal Marks

    传送门 闵神讲网络流应用的例题,来水一水 要写出这道题,需要深入理解两个概念,异或和最小割. 异或具有相对独立性,所以我们把每一位拆开来看,即做大概$32$次最小割.然后累加即可. 然后是最小割把一张 ...

随机推荐

  1. 感知器及其Python实现

    感知器是由美国计算机科学家罗森布拉特(F.Roseblatt)于1957年提出的.感知器可谓是最早的人工神经网络.单层感知器是一个具有一层神经元.采用阈值激活函数的前向网络.通过对网络权值的训练,可以 ...

  2. python_46_输出

    name='Qi Zhiguang' name2='ZhangMeng' print("Hi!"+name)#用加号,后边must be str print('Hi!',name) ...

  3. oo作业第四单元总结暨结课总结

    目录 一.第四单元作业架构设计 1.第一次UML作业架构设计 2.第二次UML作业架构设计 二.架构设计和OO方法理解演进 三.测试理解与实践的演进 四.课程收获总结 五.三个具体改进建议 一.第四单 ...

  4. form 表单 和 jQuery HTML / CSS 方法($().html 类似的样式)

    1 有关链接 :http://www.runoob.com/tags/tag-form.html https://www.cnblogs.com/Jxwz/p/4509618.html https:/ ...

  5. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第七节

    第七节:使用下一代CUDA硬件,快乐加速度 原文链接 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个 ...

  6. .NET AJAX实例

    引用地址:http://blog.csdn.net/qianjiu/article/details/7524228 5.2 Ajax基础http://book.csdn.net/bookfiles/6 ...

  7. MySQL - CASE WHEN ... THEN ... ELSE ... END语句

    范例: CASE WHEN p.allow_over = 1 THEN p.allow_over_capital ELSE 0 END

  8. 二十三、MySQL 事务

    MySQL 事务 MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数 ...

  9. exec , 元类,__new__, __call__ , 单例模式 , 异常

    1,类也是对象 ''' 动态语言 可以在运行期间 动态生成类 修改对象属性 静态语言 ''''' ''' type(object_or_name, bases, dict) type(object) ...

  10. 1 > 2 and 3 < 4 or 4 > 5 and 2 > 1 or 9 < 8

    a,b,c,d,e,f,g=1,2,3,4,5,8,9 m = a > b and c < d or c > e n = b > a or g < f x = m and ...