[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. 【BZOJ3123】[SDOI2013] 森林(启发式合并主席树)

    点此看题面 大致题意: 给你一片森林,有两种操作:询问两点之间的第\(k\)小点权和在两棵树之间连一条边. 前置技能:树上主席树 做这道题目,我们首先要会树上主席树. 关于树上主席树,这有一道很好的例 ...

  2. 2018.6.7. 云服务器Centos系统使用yum或者rpm安装包时出现问题,安装时报出错误:

    当我向终端输入 sudo yum groupinstall chinese-support 语言安装包的时候显示下面的错误 error: rpmdb: BDB0113 Thread/process 3 ...

  3. struts+hibernate+spring整合过程常见问题收集

    1.java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor缺少asm-3.3.jar2.java.lang.NoClassDefF ...

  4. Oracle分页抽数存储过程

    --outTotal是需要返回的总数,v_loginUserId是传入的登录人ID,抽取他的客户,v_CurrPage是传入的第几页,v_pageSize传入的每页数据条数. ) FROM tb_cu ...

  5. 廖老师git教程执行"git checkout -b dev origin/dev"命令报出:fatal: Cannot update paths and switch to branch 'dev' at the same time. Did you intend to checkout 'origin/dev' which can not be resolved as commit?问题解决

    在学习廖老师git教程之多人协作模块时按照老师的操作先创建了另一个目录,然后在这个目录下从GitHub上clone了 learngit目录到这个目录下,同样的执行了git branch查看分支情况,确 ...

  6. MySQL数据库的下载安装

    目录 一.概述 二.MySQL安装 三.安装成功验证 四.NavicatforMySQL下载及使用 一.MySQL下载 MySQL版本:5.7.17 下载地址:https://dev.mysql.co ...

  7. ajax400错误

    在用ajax向后台传递参数时,页面一直显示错误400 bad request. 出现这个问题的原因是,要传递的VO类里一个实体bean里面的两个字段名称与前台表单序列化之后的name名称不匹配. 解决 ...

  8. 配置管理-SpringCloudConfig

    1.搭建配置管理服务 添加依赖 <dependencies> <dependency> <groupId>org.springframework.cloud< ...

  9. tcl之变量-简单变量

  10. MySQL 时间戳与日期互相转换

    MySQL 时间戳与日期互相转换 1.时间戳转换成日期 函数:FROM_UNIXTIME() ,'%Y年%m月%d日') 结果为:2015年04月15日 2.把日期转换为时间戳,和 FROM_UNIX ...