SP839 Optimal marks(最小割)

给你一个无向图G(V,E)。 每个顶点都有一个int范围内的整数的标记。 不同的顶点可能有相同的标记。对于边(u,v),我们定义Cost(u,v)= mark [u] \(\oplus\) mark [v]。现在我们知道某些节点的标记了。你需要确定其他节点的标记,以使边的总成本尽可能小。(0 < N <= 500, 0 <= M <= 3000)

先来看一下异或的性质,由于每一位是独立的,我们可以把每一位拉出来分开考虑,变成32个子问题。

现在问题就变成了:一堆点是0,一堆点是1,一堆点没有标号,它们互相有一些边,一个边的权值只当一个点是0一个点是1时才是1,否则是0。求最小边权和

于是我们这样建图:(红色表示1,蓝色表示0,白色表示没有权值)

然后跑一个最小割即可。脑补一下,就是找出红色点势力和蓝色点势力的接触处的最小边数。

关于最小割建模的题,具体怎么操作,首先是定义割的含义,就是和s相连的点都定义成要选择的点,其它的点都不选择。关于边的值的定义,不能割的边设置成INF。这个算是套路。

由于题目要求点权和最小,因此我们应尽量让红色点最少。于是,跑完最大流以后,把从s能遍历到的点都标成1就可以满足红色点最少啦!(这个不会证,留坑。)

#include <cstdio>
#include <cstring>
using namespace std; const int maxn=505, maxm=3005, INF=1e9;
int T, n, m, k, src, dst;
inline int min(int x, int y){ return x<y?x:y; } struct Edge{
int to, nxt, f;
}e[maxm*2+maxn], e1[maxm];
int fir[maxn], cnte;
void addedge(int x, int y, int v){
Edge &ed=e[++cnte];
ed.to=y; ed.nxt=fir[x]; ed.f=v; fir[x]=cnte; }
void RESET(){ cnte=1; memset(fir, 0, sizeof(fir)); } int mark[maxn], gmark[maxn]; int dep[maxn], q[maxn], head, tail;
int bfs(){ //bfs来给图分层
head=tail=0; memset(dep, 0, sizeof(dep));
dep[src]=1; q[tail++]=src; int tmp;
while (head<tail){
tmp=q[head++];
for (int i=fir[tmp]; i>0; i=e[i].nxt)
if (e[i].f>0&&!dep[e[i].to]){
dep[e[i].to]=dep[tmp]+1;
q[tail++]=e[i].to;
}
}
return dep[dst]?1:0;
} int cur[maxn];
int dfs(int u, int flow){ //flow表示从s流到当前点的最大流量 找出一条流
if (u==dst) return flow;
if (cur[u]==-1) return 0;
for (int i=(cur[u]?cur[u]:fir[u]); i>0; i=e[i].nxt){
cur[u]=i;
if (dep[e[i].to]==dep[u]+1&&e[i].f){
int minm=dfs(e[i].to, min(flow, e[i].f));
if (minm>0){
e[i].f-=minm; e[i^1].f+=minm;
return minm;
}
}
}
cur[u]=-1;
return 0;
} void dinic(){
while (bfs()){
memset(cur, 0, sizeof(cur));
while (dfs(src, INF));
}
} bool vis[maxn];
void findzero(int u){
vis[u]=true;
for (int i=fir[u]; i; i=e[i].nxt){
if (vis[e[i].to]||!e[i].f) continue;
findzero(e[i].to);
}
} int uu[maxm], vv[maxm]; int main(){
scanf("%d", &T); int t;
while (T--){
scanf("%d%d", &n, &m); dst=n+1;
for (int i=0; i<m; ++i)
scanf("%d%d", &uu[i], &vv[i]);
scanf("%d", &k);
memset(mark, 0, sizeof(mark));
memset(gmark, 0, sizeof(gmark));
for (int i=1; i<=k; ++i){
scanf("%d", &t); gmark[t]=1;
scanf("%d", &mark[t]);
}
for (int i=0; i<31; ++i){
RESET();
for (int j=0; j<m; ++j)
addedge(uu[j], vv[j], 1), addedge(vv[j], uu[j], 1);
for (int j=1; j<=n; ++j){
if (!gmark[j]) continue;
if (mark[j]&(1<<i)) addedge(src, j, INF);
else addedge(j, dst, INF);
}
dinic();
memset(vis, 0, sizeof(vis)); findzero(src);
for (int j=1; j<=n; ++j)
if (vis[j]) mark[j]|=(1<<i);
}
for (int i=1; i<=n; ++i) printf("%d\n", mark[i]);
}
return 0;
}

SP839 Optimal marks(最小割)的更多相关文章

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

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

  2. 【BZOJ-2400】Spoj839Optimal Marks 最小割 + DFS

    2400: Spoj 839 Optimal Marks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 567  Solved: 202[Submit ...

  3. [SP839]Optimal Marks

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

  4. SPOJ839 Optimal Marks(最小割)

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

  5. spoj 839 Optimal Marks(二进制位,最小割)

    [题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17875 [题意] 给定一个图,图的权定义为边的两端点相抑或值的 ...

  6. SPOJ-OPTM Optimal Marks ★★(按位建图 && 最小割)

    [题意]给出一个无向图,每个点有一个标号mark[i],不同点可能有相同的标号.对于一条边(u, v),它的权值定义为mark[u] xor mark[v].现在一些点的标号已定,请决定剩下点的标号, ...

  7. SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)

    http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...

  8. SPOJ 839 Optimal Marks(最小割的应用)

    https://vjudge.net/problem/SPOJ-OPTM 题意: 给出一个无向图G,每个点 v 以一个有界非负整数 lv 作为标号,每条边e=(u,v)的权w定义为该边的两个端点的标号 ...

  9. Optimal Marks SPOJ - OPTM (按位枚举-最小割)

    题意:给一张无向图,每个点有其点权,边(i,j)的cost是\(val_i\ XOR \ val_j\).现在只给出K个点的权值,求如何安排其余的点,使总花费最小. 分析:题目保证权值不超过32位整型 ...

随机推荐

  1. 【转】轻舞飞扬 LTE基本架构

    这篇文章主要介绍LTE的最基础的架构,包括LTE网络的构成,每一个网络实体的作用以及LTE网络协议栈,最后还包括对一个LTE数据流的模型的说明. LTE网络参考模型 这是一张非常有名的LTE架构图,从 ...

  2. java代码随机数组合,随机号码产生器

    总结:还是掌握方法的运用++++++ package com.c2; //随机数组合,随机号码产生器 //随机号码 import java.util.Random; public class rfe ...

  3. Excel开发学习笔记:VB.net的一些杂项

    遇到一个数据处理自动化的问题,于是打算开发一个基于excel的小工具.在业余时间一边自学一边实践,抽空把一些知识写下来以备今后参考,因为走的是盲人摸象的野路子,幼稚与错误请多包涵. 开发环境基于VST ...

  4. Python命令模块argparse学习笔记(二)

    argparse模块可以设置两种命令参数,一个是位置参数,一个是命令参数 位置参数 import argparse parser = argparse.ArgumentParser(descripti ...

  5. [git更新中]版本控制工具git初步使用

    逐渐开始写规模稍大的程序, 如果在像以前一样每写完一次保存一个版本, 修改起来太蛋疼了, 而且还会忘记都有修改过哪里, 最终如果写完的话, 各种不方便, 于是便开始接触版本控制工具. 因为是在Linu ...

  6. PHP中交换两个变量的值

    首先,采用php的list数据结构.上代码,然后再解析 function swap(&$a, &$b) { list ( $a, $b ) = array ($b, $a ); } l ...

  7. DAY7-面向对象之封装

    一.引子 从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,还有alex一起装进麻袋,然后把麻袋封上口子.照这种逻辑看,封装=‘隐藏’,这种理解是相当片面的 二.先看如何隐藏 在 ...

  8. WebView三个方法区别(解决乱码问题)

    最近使用WebView加载中文网页的时候出现乱码问题,网上整理下基本解决方法: 其实我发现这不管是在线还是离线显示都可以使用LoadUrl方法!联网时好像是默认utf-8,离线读取本地时需要设置默认编 ...

  9. 洛谷P3328(bzoj 4085)毒瘤线段树

    题面及大致思路:https://www.cnblogs.com/Yangrui-Blog/p/9623294.html, https://www.cnblogs.com/New-Godess/p/45 ...

  10. win10 更换秘钥报错:拒绝访问:所请求的操作需要提升特权

    直接打开cmd执行换秘钥的命令: slmgr /ipk VK7JG-NPHTM-C97JM-9MPGT-3V66T slmgr /skms kms.xspace.in slmgr /ato 报错如图: ...