【bzoj2400】Spoj 839 Optimal Marks 网络流最小割
题目描述
输入
输出
样例输入
3 2
2
-1
0
1 2
2 3
样例输出
2
2
题解
网络流最小割
由于xor是二进制位运算,因此我们可以拆位处理。
拆位以后每个点只为0或1,相邻的点选择不同则会产生代价,问最小代价。
显然是最小割。
对于每个点,如果它已经确定,则如果其为1则向T连边,如果其为0则S向其连边,容量为inf。
对于相邻的点,相互连边,容量为1。
然后最小割即为第一问答案。
对于第二问答案,有一个神方法,可以直接跑一遍最小割就能算出来。
具体就是原来的1全部改为10000,然后S向所有点,容量为1。跑最小割时,肯定要保证割10000边的条数最小,即为第一问答案;而在此基础上每有一个数为1,则需要额外割一条1边,所以同时让割1边的条数最小,也就保证了1的个数最少。
最后把每一位的结果加起来即为答案。注意要开long long。
#include <cstdio>
#include <cstring>
#include <queue>
#define N 510
#define M 20010
using namespace std;
typedef long long ll;
const int inf = 1 << 30;
queue<int> q;
int n , m , v[N] , x[M] , y[M] , head[N] , to[M] , val[M] , next[M] , cnt , s , t , dis[N];
ll ans1 , ans2;
void add(int x , int y , int z)
{
to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
to[++cnt] = x , val[cnt] = 0 , next[cnt] = head[y] , head[y] = cnt;
}
bool bfs()
{
int x , i;
memset(dis , 0 , sizeof(dis));
while(!q.empty()) q.pop();
dis[s] = 1 , q.push(s);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && !dis[to[i]])
{
dis[to[i]] = dis[x] + 1;
if(to[i] == t) return 1;
q.push(to[i]);
}
}
}
return 0;
}
int dinic(int x , int low)
{
if(x == t) return low;
int temp = low , i , k;
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && dis[to[i]] == dis[x] + 1)
{
k = dinic(to[i] , min(temp , val[i]));
if(!k) dis[to[i]] = 0;
val[i] -= k , val[i ^ 1] += k;
if(!(temp -= k)) break;
}
}
return low - temp;
}
void solve(int k)
{
int i , c = 0;
memset(head , 0 , sizeof(head)) , cnt = 1;
for(i = 1 ; i <= n ; i ++ )
{
add(s , i , 1);
if(v[i] >= 0)
{
if(v[i] & k) add(i , t , inf);
else add(s , i , inf);
}
}
for(i = 1 ; i <= m ; i ++ ) add(x[i] , y[i] , 10000) , add(y[i] , x[i] , 10000);
while(bfs()) c += dinic(s , inf);
ans1 += (ll)c / 10000 * k , ans2 += (ll)c % 10000 * k;
}
int main()
{
int i;
scanf("%d%d" , &n , &m) , s = 0 , t = n + 1;
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &v[i]);
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &x[i] , &y[i]);
for(i = 1 << 30 ; i ; i >>= 1) solve(i);
printf("%lld\n%lld\n" , ans1 , ans2);
return 0;
}
【bzoj2400】Spoj 839 Optimal Marks 网络流最小割的更多相关文章
- SPOJ 839 Optimal Marks(最小割的应用)
https://vjudge.net/problem/SPOJ-OPTM 题意: 给出一个无向图G,每个点 v 以一个有界非负整数 lv 作为标号,每条边e=(u,v)的权w定义为该边的两个端点的标号 ...
- BZOJ2400: Spoj 839 Optimal Marks
Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其 ...
- 【BZOJ2400】Spoj 839 Optimal Marks 最小割
[BZOJ2400]Spoj 839 Optimal Marks Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...
- 【bzoj2400】Spoj 839 Optimal Marks 按位最大流
Spoj 839 Optimal Marks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 908 Solved: 347[Submit][Stat ...
- SP839 Optimal marks(最小割)
SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...
- SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)
http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...
- spoj 839 Optimal Marks(二进制位,最小割)
[题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17875 [题意] 给定一个图,图的权定义为边的两端点相抑或值的 ...
- BZOJ 2400: Spoj 839 Optimal Marks (按位最小割)
题面 一个无向图,一些点有固定权值,另外的点权值由你来定. 边的值为两点的异或值,一个无向图的值定义为所有边的值之和. 求无向图的最小值 分析 每一位都互不干扰,按位处理. 用最小割算最小值 保留原图 ...
- SPOJ839 Optimal Marks(最小割)
题目大概说给一张图,每个点都有权,边的权等于其两端点权的异或和,现已知几个点的权,为了使所有边的边权和最小,其他点的权值该是多少. 很有意思的一道题,完全看不出和网络流有什么关系. 考虑每个未知的点$ ...
随机推荐
- python爬虫之路——初识爬虫原理
爬虫主要做两件事 ①模拟计算机对服务器发起Request请求 ②接收服务器端的Response内容并解析,提取所需的信息 互联网页面错综复杂,一次请求不能获取全部信息.就需要设计爬虫的流程. 本书主要 ...
- 卓越管理的实践技巧(4)如何才能给予有效的反馈 Guide to Giving Effective Feedback
Guide to Giving Effective Feedback 前文卓越管理的秘密(Behind Closed Doors)最后一部分提到了总结的13条卓越管理的实践技巧并列出了所有实践技巧名称 ...
- 《学习CSS布局》学习笔记
近几天做了一个小的企业展示网站.虽然页面是在模板的基础上改的,但改的多了不熟悉CSS也很麻烦.正好我看到了学习CSS布局这个网站,于是补习了一下CSS知识. CSS的显示 CSS的元素分为两类:块级元 ...
- WPF知识点全攻略11- 命令(Command)
先看一下命令的简单使用: <Window.CommandBindings> <CommandBinding Command="ApplicationCommands.Cut ...
- 2018.4.28 基于java的聊天系统(带完善)
Java聊天系统 1.Socket类 Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号. Socket(String ...
- Python 继承、派生、组合、接口、抽象类
继承是一种是的关系,和组合对比,组合是一种有的关系,这两者都是解决代用重用问题的 继承 注意:继承不是遗传,在显示角度中,是通过对象抽象成类,再把这些类抽象成一个,就是父类.是自下而上的过程,在程序中 ...
- GTA5(侠盗猎车5)中文版破解版
)中文版破解版迅雷下载地址(使用迅雷新建任务填上地址): magnet:?xt=urn:btih:65F16B126D8A656E4FC825DE204EBFAF04B070FC
- IDEA设置每次打开重新选择项目
通过这里,选择settings,或者进入之后的FILE->settings.搜索System 即可出现
- 01_12_JSP简介
01_12_JSP简介 1. JSP简介 JSP---Java Server Pages 拥有servlet的特性与优点(本身就是一个servlet) 直接在HTML中内嵌JSP代码 JSP程序有JS ...
- 为什么方差的分母有时是n,有时是n-1 源于总体方差和样本方差的不同
为什么样本方差(sample variance)的分母是 n-1? 样本方差计算公式里分母为n-1的目的是为了让方差的估计是无偏的.无偏的估计(unbiased estimator)比有偏估计(bia ...