首先肯定每一位单独考虑,对于每一位,源点连向该位点权为0的节点inf的边,点权为1的节点连向汇点inf的边,每一条无向边拆成两条流量为1的有向边,跑最小割。

考虑一组割,一定将原图划分成源点和汇点两部分,那么左半部分都选0,右半部分都选1,那么它的代价就是割的代价,即要求最小割。

为了让点的值最小,相当于要让汇点集合的点数尽量少,那么直接从汇点搜一遍,将所有能走到的节点记为1,其他记为0即可。

还有一种做法比较神奇,将两点之间的边权增加为10000(需要大于总点数即可),然后再让源点向每一个点再连一条1的边,最小割一定是在10000最少的前提下(即图的点权最小)让源点割掉的点最少(源点割掉的每一条边都是到汇点集合的点)。

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 #define N 505
  4. 4 #define inf 0x3f3f3f3f
  5. 5 struct ji{
  6. 6 int nex,to,len;
  7. 7 }e[N*20],edge[N*20];
  8. 8 queue<int>q;
  9. 9 int E,EE,n,m,x,y,a[N],w[N],head[N],work[N],d[N];
  10. 10 long long ans1,ans2;
  11. 11 void add(int x,int y,int z){
  12. 12 edge[E].nex=head[x];
  13. 13 edge[E].to=y;
  14. 14 edge[E].len=z;
  15. 15 head[x]=E++;
  16. 16 if (E&1)add(y,x,0);
  17. 17 }
  18. 18 bool bfs(){
  19. 19 memset(d,-1,sizeof(d));
  20. 20 q.push(0);
  21. 21 d[0]=0;
  22. 22 while (!q.empty()){
  23. 23 int k=q.front();
  24. 24 q.pop();
  25. 25 for(int i=head[k];i!=-1;i=edge[i].nex)
  26. 26 if ((edge[i].len)&&(d[edge[i].to]<0)){
  27. 27 d[edge[i].to]=d[k]+1;
  28. 28 q.push(edge[i].to);
  29. 29 }
  30. 30 }
  31. 31 return d[n+1]>=0;
  32. 32 }
  33. 33 int dfs(int k,int s){
  34. 34 if (k>n)return s;
  35. 35 int p;
  36. 36 for(int &i=work[k];i!=-1;i=edge[i].nex)
  37. 37 if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
  38. 38 p=dfs(edge[i].to,min(s,edge[i].len));
  39. 39 if (p){
  40. 40 edge[i].len-=p;
  41. 41 edge[i^1].len+=p;
  42. 42 return p;
  43. 43 }
  44. 44 }
  45. 45 return 0;
  46. 46 }
  47. 47 int dinic(){
  48. 48 int k,ans=0;
  49. 49 while (bfs()){
  50. 50 memcpy(work,head,sizeof(head));
  51. 51 while (k=dfs(0,inf))ans+=k;
  52. 52 }
  53. 53 return ans;
  54. 54 }
  55. 55 int main(){
  56. 56 scanf("%d%d",&n,&m);
  57. 57 memset(head,-1,sizeof(head));
  58. 58 for(int i=1;i<=n;i++)scanf("%d",&w[i]);
  59. 59 for(int i=1;i<=m;i++){
  60. 60 scanf("%d%d",&x,&y);
  61. 61 add(x,y,10000);
  62. 62 add(y,x,10000);
  63. 63 }
  64. 64 for(int i=1;i<=n;i++)
  65. 65 if (w[i]<0)add(0,i,1);
  66. 66 else ans2+=w[i];
  67. 67 EE=E;
  68. 68 memcpy(a,head,sizeof(a));
  69. 69 memcpy(e,edge,sizeof(e));
  70. 70 for(int i=0;i<31;i++){
  71. 71 E=EE;
  72. 72 memcpy(head,a,sizeof(a));
  73. 73 memcpy(edge,e,sizeof(e));
  74. 74 for(int j=1;j<=n;j++)
  75. 75 if (w[j]>=0)
  76. 76 if (w[j]&(1<<i))add(j,n+1,inf);
  77. 77 else add(0,j,inf);
  78. 78 int p=dinic();
  79. 79 ans1+=p/10000*(1LL<<i);
  80. 80 ans2+=p%10000*(1LL<<i);
  81. 81 }
  82. 82 printf("%lld\n%lld",ans1,ans2);
  83. 83 }

[bzoj2400]Optimal Marks的更多相关文章

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

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

  2. 【bzoj2400】Spoj 839 Optimal Marks 按位最大流

    Spoj 839 Optimal Marks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 908  Solved: 347[Submit][Stat ...

  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. [SPOJ839]Optimal Marks

    [SPOJ839]Optimal Marks 试题描述 You are given an undirected graph \(G(V, E)\). Each vertex has a mark wh ...

  7. Optimal Marks(optimal)

    Optimal Marks(optimal) 题目描述 定义无向图边的值为这条边连接的两个点的点权异或值. 定义无向图的值为无向图中所有边的值的和. 给定nn个点mm条边构成的图.其中有些点的权值是给 ...

  8. BZOJ2400: Spoj 839 Optimal Marks

    Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其 ...

  9. 【bzoj2400】Spoj 839 Optimal Marks 网络流最小割

    题目描述 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其余的点的值由你 ...

随机推荐

  1. C语言实现简易计算器(可作加减乘除)

    C语言实现简易计算器(加减乘除) 计算器作为课设项目,已完成答辩,先将代码和思路(注释中)上传一篇博客 已增添.修改.整理至无错且可正常运行 虽使用了栈,但初学者可在初步了解栈和结构语法后理解代码 # ...

  2. 手把手教你 Docker部署可视化工具Grafana

    一.Grafana的简单介绍 Grafana是开源的.炫酷的可视化监控.分析利器,无论您的数据在哪里,或者它所处的数据库是什么类型,您都可以将它与Grafana精美地结合在一起.它还有丰富的套件供您选 ...

  3. MySQL8 根据某属性查询字段排名由自定义变量到rank()的变动

    在mysql8 之前的版本,因为没有rank()方法的存在,所以在对字段进行排名时,使用的是自定义自变量的方法,比如: select id,name,@rank=@rank+1 as ranks fr ...

  4. 洛谷1501 Tree II(LCT,路径修改,路经询问)

    这个题是一个经典的维护路径信息的题,对于路径上的修改,我们只需要把对应的链\(split\)上来,然后修改最上面的点就好,注意pushdown的时候的顺序是先乘后加 然后下传乘法标记的时候,记得把对应 ...

  5. AIbee 笔试

    CSS选择器 div+p 选择紧接在div元素之后的所有< p >元素 C++删除数组最后一个元素. 例如[1 2 3 4] 最后变为 [1 2 3] 用splice的删除,增加和替换 a ...

  6. 第五章第四周习题: Transformers Architecture with TensorFlow

    目录 Transformer Network Packages 1 - Positional Encoding 1.1 - Sine and Cosine Angles Exercise 1 - ge ...

  7. 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请求连接更加的快速,而且是 一个长链接,方便于这个项目进行其他 ...

  8. 简明教程 | Docker篇 · 其一:基础入门

    了解Docker Docker是什么 Docker是指容器化技术,用于支持创建和使用 Linux 容器,同时Docker也是软件容器平台. 什么是容器(container) 容器是主机上与其他进程隔离 ...

  9. 「刷题」THUPC泛做

    刷了一下,写一下. T1. 天天爱射击 可以这样想. 我们二分一下每一块木板在什么时刻被击碎. 然后直接用主席树维护的话是\(O(nlog^2n)\)的. 会\(T\),而且是一分不给那种... 那么 ...

  10. 用python检查矩阵的计算

    鉴于最近复习线性代数计算量较大,且1800答案常常忽略一些逆阵.行列式的计算答案,故用Python写出矩阵的简单计算程序,便于检查出错的步骤. 1.行列式 可自行更改阶数 from numpy imp ...