[bzoj2400]Optimal Marks
首先肯定每一位单独考虑,对于每一位,源点连向该位点权为0的节点inf的边,点权为1的节点连向汇点inf的边,每一条无向边拆成两条流量为1的有向边,跑最小割。
考虑一组割,一定将原图划分成源点和汇点两部分,那么左半部分都选0,右半部分都选1,那么它的代价就是割的代价,即要求最小割。
为了让点的值最小,相当于要让汇点集合的点数尽量少,那么直接从汇点搜一遍,将所有能走到的节点记为1,其他记为0即可。
还有一种做法比较神奇,将两点之间的边权增加为10000(需要大于总点数即可),然后再让源点向每一个点再连一条1的边,最小割一定是在10000最少的前提下(即图的点权最小)让源点割掉的点最少(源点割掉的每一条边都是到汇点集合的点)。
- 1 #include<bits/stdc++.h>
- 2 using namespace std;
- 3 #define N 505
- 4 #define inf 0x3f3f3f3f
- 5 struct ji{
- 6 int nex,to,len;
- 7 }e[N*20],edge[N*20];
- 8 queue<int>q;
- 9 int E,EE,n,m,x,y,a[N],w[N],head[N],work[N],d[N];
- 10 long long ans1,ans2;
- 11 void add(int x,int y,int z){
- 12 edge[E].nex=head[x];
- 13 edge[E].to=y;
- 14 edge[E].len=z;
- 15 head[x]=E++;
- 16 if (E&1)add(y,x,0);
- 17 }
- 18 bool bfs(){
- 19 memset(d,-1,sizeof(d));
- 20 q.push(0);
- 21 d[0]=0;
- 22 while (!q.empty()){
- 23 int k=q.front();
- 24 q.pop();
- 25 for(int i=head[k];i!=-1;i=edge[i].nex)
- 26 if ((edge[i].len)&&(d[edge[i].to]<0)){
- 27 d[edge[i].to]=d[k]+1;
- 28 q.push(edge[i].to);
- 29 }
- 30 }
- 31 return d[n+1]>=0;
- 32 }
- 33 int dfs(int k,int s){
- 34 if (k>n)return s;
- 35 int p;
- 36 for(int &i=work[k];i!=-1;i=edge[i].nex)
- 37 if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
- 38 p=dfs(edge[i].to,min(s,edge[i].len));
- 39 if (p){
- 40 edge[i].len-=p;
- 41 edge[i^1].len+=p;
- 42 return p;
- 43 }
- 44 }
- 45 return 0;
- 46 }
- 47 int dinic(){
- 48 int k,ans=0;
- 49 while (bfs()){
- 50 memcpy(work,head,sizeof(head));
- 51 while (k=dfs(0,inf))ans+=k;
- 52 }
- 53 return ans;
- 54 }
- 55 int main(){
- 56 scanf("%d%d",&n,&m);
- 57 memset(head,-1,sizeof(head));
- 58 for(int i=1;i<=n;i++)scanf("%d",&w[i]);
- 59 for(int i=1;i<=m;i++){
- 60 scanf("%d%d",&x,&y);
- 61 add(x,y,10000);
- 62 add(y,x,10000);
- 63 }
- 64 for(int i=1;i<=n;i++)
- 65 if (w[i]<0)add(0,i,1);
- 66 else ans2+=w[i];
- 67 EE=E;
- 68 memcpy(a,head,sizeof(a));
- 69 memcpy(e,edge,sizeof(e));
- 70 for(int i=0;i<31;i++){
- 71 E=EE;
- 72 memcpy(head,a,sizeof(a));
- 73 memcpy(edge,e,sizeof(e));
- 74 for(int j=1;j<=n;j++)
- 75 if (w[j]>=0)
- 76 if (w[j]&(1<<i))add(j,n+1,inf);
- 77 else add(0,j,inf);
- 78 int p=dinic();
- 79 ans1+=p/10000*(1LL<<i);
- 80 ans2+=p%10000*(1LL<<i);
- 81 }
- 82 printf("%lld\n%lld",ans1,ans2);
- 83 }
[bzoj2400]Optimal Marks的更多相关文章
- 【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 ...
- 图论(网络流):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 ...
- SP839 Optimal marks(最小割)
SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...
- [SPOJ839]Optimal Marks
[SPOJ839]Optimal Marks 试题描述 You are given an undirected graph \(G(V, E)\). Each vertex has a mark wh ...
- Optimal Marks(optimal)
Optimal Marks(optimal) 题目描述 定义无向图边的值为这条边连接的两个点的点权异或值. 定义无向图的值为无向图中所有边的值的和. 给定nn个点mm条边构成的图.其中有些点的权值是给 ...
- BZOJ2400: Spoj 839 Optimal Marks
Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其 ...
- 【bzoj2400】Spoj 839 Optimal Marks 网络流最小割
题目描述 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其余的点的值由你 ...
随机推荐
- C语言实现简易计算器(可作加减乘除)
C语言实现简易计算器(加减乘除) 计算器作为课设项目,已完成答辩,先将代码和思路(注释中)上传一篇博客 已增添.修改.整理至无错且可正常运行 虽使用了栈,但初学者可在初步了解栈和结构语法后理解代码 # ...
- 手把手教你 Docker部署可视化工具Grafana
一.Grafana的简单介绍 Grafana是开源的.炫酷的可视化监控.分析利器,无论您的数据在哪里,或者它所处的数据库是什么类型,您都可以将它与Grafana精美地结合在一起.它还有丰富的套件供您选 ...
- MySQL8 根据某属性查询字段排名由自定义变量到rank()的变动
在mysql8 之前的版本,因为没有rank()方法的存在,所以在对字段进行排名时,使用的是自定义自变量的方法,比如: select id,name,@rank=@rank+1 as ranks fr ...
- 洛谷1501 Tree II(LCT,路径修改,路经询问)
这个题是一个经典的维护路径信息的题,对于路径上的修改,我们只需要把对应的链\(split\)上来,然后修改最上面的点就好,注意pushdown的时候的顺序是先乘后加 然后下传乘法标记的时候,记得把对应 ...
- AIbee 笔试
CSS选择器 div+p 选择紧接在div元素之后的所有< p >元素 C++删除数组最后一个元素. 例如[1 2 3 4] 最后变为 [1 2 3] 用splice的删除,增加和替换 a ...
- 第五章第四周习题: Transformers Architecture with TensorFlow
目录 Transformer Network Packages 1 - Positional Encoding 1.1 - Sine and Cosine Angles Exercise 1 - ge ...
- The WebSocket session [0] has been closed and no method (apart from close()) may be called on a closed session-ConcurrentHashMap使用在webSocket中采的坑
一.问题由来 现在开发的一个项目中使用webSocket这个技术和Unity客户端程序进行联动操作,因为socket连接相对来说比http请求连接更加的快速,而且是 一个长链接,方便于这个项目进行其他 ...
- 简明教程 | Docker篇 · 其一:基础入门
了解Docker Docker是什么 Docker是指容器化技术,用于支持创建和使用 Linux 容器,同时Docker也是软件容器平台. 什么是容器(container) 容器是主机上与其他进程隔离 ...
- 「刷题」THUPC泛做
刷了一下,写一下. T1. 天天爱射击 可以这样想. 我们二分一下每一块木板在什么时刻被击碎. 然后直接用主席树维护的话是\(O(nlog^2n)\)的. 会\(T\),而且是一分不给那种... 那么 ...
- 用python检查矩阵的计算
鉴于最近复习线性代数计算量较大,且1800答案常常忽略一些逆阵.行列式的计算答案,故用Python写出矩阵的简单计算程序,便于检查出错的步骤. 1.行列式 可自行更改阶数 from numpy imp ...