SPOJ-OPTM Optimal Marks ★★(按位建图 && 最小割)
【题意】给出一个无向图,每个点有一个标号mark[i],不同点可能有相同的标号。对于一条边(u, v),它的权值定义为mark[u] xor mark[v]。现在一些点的标号已定,请决定剩下点的标号,使得总的边权和最小。(0 < N <= 500, 0 <= M <= 3000, 0 <= mark[i] <= 2^31-1)
胡伯涛神牛《最小割模型在信息学竞赛中的应用》中的例题。非常好的一道题!非常推荐!
【思路】
我们把问题数学化就是: Minimum sigma(we) = sigma(u, v)∈E ( mark(u) xor mark(v) )
对于异或问题,我们发现这样的二进制按位运算各个二进制位之间是互不影响的,所以我们可以一位一位的做这类题。
那么我们的式子又可以进一步转化为:
Minimum sigma(u, v)∈E { sigmai=0~oo(2^i) • sigma(mark(u, i) xor mark(v, i)) }
这样我们就把mark的限制加强了:只可能是0或1。即这些点将分成两类。
再观察我们发现,xor运算,只有当u、v不同时结果才为1,即这样的有效边的两端点一定属于不同点集。这像什么?不就是割边嘛!~而题目正好又是要求最小,这样问题便转化为最小割了~ (要注意培养这种问题转化和模型发现的能力!)
那么具体的最小割网络GN模型:建一个源点,向每一个标号为1的点连一条oo流量的边(后面解释为什么源点连标号1的点);建一个汇点,向每一个标号为0的点连一条oo流量的边;原图中的边容量设为1加入到GN中。求出来的最小割便是该二进制位下的标号xor的和最小的情况。
然而题目还要求输出所有点的标号,并且需要标号的和也最小。那么怎么保证标号的和最小呢?无非就是尽可能的取0。那么又该怎么做?
首先先看怎么给那些未标号的点标号:容易想到最小割把网络分成了两个点集,那么显然每个点标号应该和它所在点集已标号的点一致,所以当然希望标号为0的点集点更多一些。然后注意我们划分点集是从源点开始dfs,那么这样划出来的最小割边集显然更偏向源点,即这样划分出来的S集点是最少的。于是源点当然连标号为1的点呐~
【代码】
#include
#include
#include
#include
#include
#include
#define MID(x,y) ((x+y)/2)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MAXV = 505;
const int MAXE = 10005;
const int oo = 0x3fffffff;/* Dinic-2.0-2013.07.21: adds template. double & int 转换方便多了,也不易出错 ~*/
template
struct Dinic{
struct node{
int u, v;
T flow;
int opp;
int next;
}arc[2*MAXE];
int vn, en, head[MAXV];
int cur[MAXV];
int q[MAXV];
int path[2*MAXE], top;
int dep[MAXV];
void init(int n){
vn = n;
en = 0;
mem(head, -1);
}
void insert_flow(int u, int v, T flow){
arc[en].u = u;
arc[en].v = v;
arc[en].flow = flow;
arc[en].next = head[u];
head[u] = en ++;arc[en].u = v;
arc[en].v = u;
arc[en].flow = 0;
arc[en].next = head[v];
head[v] = en ++;
}
bool bfs(int s, int t){
mem(dep, -1);
int lq = 0, rq = 1;
dep[s] = 0;
q[lq] = s;
while(lq 0){
dep[v] = dep[u] + 1;
q[rq ++] = v;
}
}
}
return false;
}
T solve(int s, int t){
T maxflow = 0;
while(bfs(s, t)){
int i, j;
for (i = 1; i arc[path[k]].flow){
minflow = arc[path[k]].flow;
mink = k;
}
for (int k = 0; k dinic;
int mark[MAXV];
bool if_mark[MAXV];
struct path{
int u, v;
}p[MAXE];
bool vis[MAXV];
int st[MAXV]; //ST集
void dfs(int u){
vis[u] = 1;
st[u] = 1;
for (int i = dinic.head[u]; i != -1; i = dinic.arc[i].next){
if (dinic.arc[i].flowSPOJ-OPTM Optimal Marks ★★(按位建图 && 最小割)的更多相关文章
- 【bzoj2400】Spoj 839 Optimal Marks 按位最大流
Spoj 839 Optimal Marks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 908 Solved: 347[Submit][Stat ...
- 图论(网络流):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 ...
- BZOJ 2400: Spoj 839 Optimal Marks (按位最小割)
题面 一个无向图,一些点有固定权值,另外的点权值由你来定. 边的值为两点的异或值,一个无向图的值定义为所有边的值之和. 求无向图的最小值 分析 每一位都互不干扰,按位处理. 用最小割算最小值 保留原图 ...
- hdu 5294 Tricks Device 最短路建图+最小割
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Tricks Device Time Limit: 2000/1000 MS (Java/Other ...
- Luogu SP839 OPTM - Optimal Marks(按位最小割)
这道题和 BZOJ 2400 是一道题,不多讲了 CODE #include <cstdio> #include <cstring> #include <vector&g ...
- BZOJ 1475 & 1324 && 建图最小割
题意: 给一个矩阵,取其中一方格中的数,满足所有所取方格不相邻. SOL: 典型一个二分图,染色后不相邻的连边即可.跑个最大流,裸裸哒. Code: 代码没什么时间写了...并不是很想贴...都是贴板 ...
- 【BZOJ2400】Spoj 839 Optimal Marks 最小割
[BZOJ2400]Spoj 839 Optimal Marks Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...
- SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)
http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...
随机推荐
- Kakfa揭秘 Day4 Kafka中分区深度解析
Kakfa揭秘 Day4 Kafka中分区深度解析 今天主要谈Kafka中的分区数和consumer中的并行度.从使用Kafka的角度说,这些都是至关重要的. 分区原则 Partition代表一个to ...
- exec php
$m = memory_get_usage(); echo $m; require_once('include/entryPoint.php'); // for ($i=0; $i < 5000 ...
- chown
chown 命令 用途:更改与文件关联的所有者或组 chown [ -f ] [ -h ] [ -R ] Owner [ :Group ] { File ... | Directory ... } c ...
- MQ 2035(MQRC_NOT_AUTHORIZED)
当使用MQ7.1或7.5时,如果使用MQ管理员账号去连接MQ服务器,可能会报以下的错误,提示你权限不足. 2035 MQRC_NOT_AUTHORIZED 在之前的版本中是没有这个问题的. 原因是在7 ...
- EXTJS 4.2 资料 控件之Grid 列鼠标悬停提示
columns: [ { header: }, { header: }, { header: , renderer: function (v, ctx, record) { ctx.tdAttr = ...
- C# Windows - ListView
ListView控件的属性 属性 说明 Activation 控制用户在列表视图中激活选项的方式Standard - 用户为自己的计算机选择的值OneClick – 单击一个选项,激活它TwoClic ...
- poj 1679 The Unique MST(唯一的最小生成树)
http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submis ...
- 怎样快糙猛的开始搞Kaggle比赛
- js获取fck值的代码方法
引入js文件 <script type="text/javascript" src="${basePath}/FCKeditor/fckeditor.js" ...
- HDU4545+LCS
最长公共子序列. /* LCS 最长公共子序列 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...