Spoj 839 Optimal Marks

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 908  Solved: 347
[Submit][Status][Discuss]

Description

定义无向图中的一条边的值为:这条边连接的两个点的值的异或值。
定义一个无向图的值为:这个无向图所有边的值的和。
给你一个有n个结点m条边的无向图。其中的一些点的值是给定的,而其余的点的值由你决定(但要求均为非负数),使得这个无向图的值最小。在无向图的值最小的前提下,使得无向图中所有点的值的和最小。
 

Input

第一行,两个数n,m,表示图的点数和边数。
接下来n行,每行一个数,按编号给出每个点的值(若为负数则表示这个点的值由你决定,值的绝对值大小不超过10^9)。
接下来m行,每行二个数a,b,表示编号为a与b的两点间连一条边。(保证无重边与自环。)
 

Output

    第一行,一个数,表示无向图的值。
    第二行,一个数,表示无向图中所有点的值的和。
 

Sample Input

3 2
2
-1
0
1 2
2 3

Sample Output

2
2

HINT

数据约定

n<=500,m<=2000

样例解释

2结点的值定为0即可。

因为是xor,可以从按位的思考

这种两个答案的,二维偏序差不多,一般会想到费用流,

但是这里可以是图的权值扩大到点权和到达不了的状态,即不由点权和影响。

这样/mx 为图的权值,%mx为点的权和。

然后考虑建图,设S为0集合,T为1集合,所以只需要考虑边两个端点一个选S,一个选T这样才会产生值。

看限制了,如果当前这位有值,那么就按这个赋值,如果是1,那么S-i为inf,i-T为1;

这样的,边的话,就是10000的边。

具体看代码。

每次的最大流的意义不同,代表1<<i。

  1. #include<cstring>
  2. #include<cmath>
  3. #include<iostream>
  4. #include<cstdio>
  5. #include<algorithm>
  6. #include<queue>
  7.  
  8. #define inf 1000000007
  9. #define ll long long
  10. #define N 507
  11. #define M 20007
  12. using namespace std;
  13. inline int read()
  14. {
  15. int x=,f=;char ch=getchar();
  16. while(ch<''||ch>''){if (ch=='-')f=-;ch=getchar();}
  17. while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
  18. return x*f;
  19. }
  20.  
  21. int n,m,S,T;
  22. int num[N];
  23. int cnt,hed[N],nxt[M],rea[M],val[M],cur[N];
  24. int dis[N];
  25. ll ans1,ans2;
  26. struct Node
  27. {
  28. int x,y;
  29. }a[M];
  30.  
  31. void add(int u,int v,int w)
  32. {
  33. nxt[++cnt]=hed[u];
  34. hed[u]=cnt;
  35. rea[cnt]=v;
  36. val[cnt]=w;
  37. }
  38. void add_two_edge(int u,int v,int w)
  39. {
  40. add(u,v,w);
  41. add(v,u,);
  42. }
  43. void build(int x)
  44. {
  45. memset(hed,-,sizeof(hed)),cnt=;
  46. for (int i=;i<=n;i++)
  47. if (num[i]<) add_two_edge(i,T,);
  48. else
  49. {
  50. if (num[i]&(<<x))add_two_edge(S,i,inf),add_two_edge(i,T,);
  51. else add_two_edge(i,T,inf);
  52. }
  53. for (int i=;i<=m;i++)
  54. add_two_edge(a[i].x,a[i].y,),
  55. add_two_edge(a[i].y,a[i].x,);
  56. }
  57. bool bfs()
  58. {
  59. for (int i=S;i<=T;i++)dis[i]=-;
  60. dis[S]=;
  61. queue<int>q;q.push(S);
  62. while(!q.empty())
  63. {
  64. int u=q.front();q.pop();
  65. for (int i=hed[u];i!=-;i=nxt[i])
  66. {
  67. int v=rea[i],fee=val[i];
  68. if (dis[v]!=-||!fee)continue;
  69. dis[v]=dis[u]+;
  70. if (v==T)return ;
  71. q.push(v);
  72. }
  73. }
  74. return ;
  75. }
  76. ll dfs(int u,int MX)
  77. {
  78. ll res=;
  79. if (MX==||u==T)return MX;
  80. for (int i=cur[u];i!=-;i=nxt[i])
  81. {
  82. int v=rea[i],fee=val[i];
  83. if (dis[v]!=dis[u]+)continue;
  84. int x=dfs(v,min(MX,fee));
  85. cur[u]=i,res+=x,MX-=x;
  86. val[i]-=x,val[i^]+=x;
  87. if (MX==) break;
  88. }
  89. if (!res)dis[u]=-;
  90. return res;
  91. }
  92. ll dinic()
  93. {
  94. ll res=;
  95. while(bfs())
  96. {
  97. for (int i=S;i<=T;i++)cur[i]=hed[i];
  98. res+=dfs(,inf);
  99. }
  100. return res;
  101. }
  102. int main()
  103. {
  104. n=read(),m=read(),S=,T=n+;int mx=-;
  105. for (int i=;i<=n;i++)
  106. {
  107. num[i]=read();
  108. mx=max(mx,num[i]);
  109. }
  110. for (int i=;i<=m;i++)a[i].x=read(),a[i].y=read();
  111. for (int i=;(<<i)<=mx;i++)
  112. {
  113. build(i);
  114. ll res=dinic();
  115. ans1+=(res/)*(ll)(<<i);
  116. ans2+=(res%)*(ll)(<<i);
  117. }
  118. printf("%lld\n%lld\n",ans1,ans2);
  119. }

【bzoj2400】Spoj 839 Optimal Marks 按位最大流的更多相关文章

  1. BZOJ2400: Spoj 839 Optimal Marks

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

  2. BZOJ 2400: Spoj 839 Optimal Marks (按位最小割)

    题面 一个无向图,一些点有固定权值,另外的点权值由你来定. 边的值为两点的异或值,一个无向图的值定义为所有边的值之和. 求无向图的最小值 分析 每一位都互不干扰,按位处理. 用最小割算最小值 保留原图 ...

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

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

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

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

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

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

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

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

  7. 图论(网络流):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 ...

  8. SPOJ OPTM - Optimal Marks

    OPTM - Optimal Marks no tags  You are given an undirected graph G(V, E). Each vertex has a mark whic ...

  9. 839. Optimal Marks - SPOJ

    You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range ...

随机推荐

  1. ES6 Promise用法详解

    What is Promise? Promise是一个构造函数,接受一个参数(Function),并且该参数接受两个参数resolve和reject(分别表示异步操作执行成功后的回调函数.执行失败后的 ...

  2. 使TextBox的内容换行

    首先你把TextBox控件的MultiLine属性设置为True,然后把TextBox控件的Text属性根据程序需要,在需要换行的地方加入\r\n这样就可实现换行了

  3. AngularJS 应用

    AngularJS模块(Module)定义了AngularJS的应用. AngularJS控制器(Controller)用于控制AngularJS应用. ng-app指令定义了应用,ng-contro ...

  4. C#赋值运算符

    一.C#赋值运算符 C#语言的赋值运算符用于将一个数据赋予一个变量.属性或者引用.数据可以是常量.变量或者表达式. 1. 简单赋值 “=”操作符被称为简单赋值操作符.在一个简单赋值中,右操作数必须为某 ...

  5. 3170: [Tjoi2013]松鼠聚会

    Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1804  Solved: 968[Submit][Status][Discuss] Descript ...

  6. 1025: [SCOI2009]游戏

    Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2727  Solved: 1794[Submit][Status][Discuss] Descripti ...

  7. Ubuntu12.04下YouCompleteMe安装教程(部分)

    1.通过源码编译安装VIM 开发中使用的是Ubuntu 12.04 LTS,通过sudo apt-get install vim安装的版本较低,不支持YCM,所以,用源码编译并安装最新的Vim. 卸载 ...

  8. Play on Words HDU - 1116 (并查集 + 欧拉通路)

    Play on Words HDU - 1116 Some of the secret doors contain a very interesting word puzzle. The team o ...

  9. Elastic Search和Kibana入门

    一.ES配置 二.ES本地快速搭建集群 查看ES集群 查看node详细情况 三.Kibana配置 修改kibana的es配置 访问localhost:5601端口 四.Elasticsearch 术语 ...

  10. Python对文本文件的简单操作(一)

    工作背景 性能测试工程师,主要测试工具--loadrunner,主要是接口测试. 实现功能 loadrunner对报文格式的转换存在问题,部分报文无法转换,故使用Python编写脚本自动将soap协议 ...