[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. iOS Dispatch_sync 阻塞线程的原因

    大家的知道在主队列上使用dispatch_sync(), - (void)testSyncMainThread { dispatch_queue_t main = dispatch_get_main_ ...

  2. SQLAlchemy简介

    一.SQLAlchemy简介 SQLAlchemy是Python SQL工具包和对象关系映射器,是python中最著名的ORM(Object Relationship Mapping)框架,它简化了应 ...

  3. 数组逆序=全局内存版 VS 共享内存版

    全局内存版 #include <stdio.h> #include <assert.h> #include "cuda.h" #include " ...

  4. android设备局域网中快速搜索之cling方式

    cling方式就像pc端windows局域网工作组刷新显示一样,原来用过扫描ip地址的方式,可以使用就是有点慢,还有一种自己加入组广播,通过发送组广播的方式.   android设备局域网中快速搜索之 ...

  5. jQuery Pagination分页插件--刷新

    源码地址:https://github.com/SeaLee02/FunctionModule/blob/master/UploadFiles/WebDemo/FenYE/FenYeDemo.aspx ...

  6. oc block排序

    NSArray *sortArr=[arr sortedArrayUsingSelector:@selector(compareWithClassAndName:)]; //数组排序--block N ...

  7. 【Django】Django中的模糊查询以及Q对象的简单使用

    Django中的模糊查询: 需要做一个查找的功能,所以需要使用到模糊查询. 使用方法是:字段名加上双下划线跟上contains或者icontains,icontains和contains表示是否区分大 ...

  8. mysql 查询 7天内的数据

    SELECT ID,SERVICE FROM new_schedules_spider_full WHERE SERVICE = 'WSA2' and date_sub(curdate(), inte ...

  9. base64转图片上传

    不成功,但是有一定的借鉴性 /** * @param base64Codes * 图片的base64编码 */ function sumitImageFile(base64Codes){ consol ...

  10. SpringSecurity项目报错

    启动时,提示: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory be ...