You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range [0..231 – 1]. Different vertexes may have the same mark.

For an edge (u, v), we define Cost(u, v) = mark[u] xor mark[v].

Now we know the marks of some certain nodes. You have to determine the marks of other nodes so that the total cost of edges is as small as possible.

Input

The first line of the input data contains integer T (1 ≤ T ≤ 10) - the number of testcases. Then the descriptions of T testcases follow.

First line of each testcase contains 2 integers N and M (0 < N <= 500, 0 <= M <= 3000). N is the number of vertexes and M is the number of edges. Then M lines describing edges follow, each of them contains two integers u, v representing an edge connecting u and v.

Then an integer K, representing the number of nodes whose mark is known. The next K lines contain 2 integers u and p each, meaning that node u has a mark p. It’s guaranteed that nodes won’t duplicate in this part.

Output

For each testcase you should print N lines integer the output. The Kth line contains an integer number representing the mark of node K. If there are several solutions, you have to output the one which minimize the sum of marks. If there are several solutions, just output any of them.

Example

  1. Input:
  2. 1
  3. 3 2
  4. 1 2
  5. 2 3
  6. 2
  7. 1 5
  8. 3 100
  9.  
  10. Output:
  11. 5
  12. 4
  13. 100
  14.  
  15. 题目大意:
    每一条边的权值定义为x xor y,(x,y是两端点),有一些点的权值已知,求剩下的点怎么弄,是总边权最小。
    题解:
    首先要知道xor操作时,二进制的每一位都是独立的,不相互影响,所以可以分开处理。
    对于每一位,我们把未知的点初始为0,然后对已知的进行操作:当前位为1Si有一条边,容量为INF,为0则到T有一条为INF边。
    然后对于每一条边:(ij)拆成(i,j,1)(j,i,1)
    然后跑最小割,可以发现对于每一个子图,最小割不是割在T就是割在S,割在T表示前面一堆点都设为1
    因为已知的10),隔在S表示后面一堆点都设为0(因为已知的01多)
    知道了这个,于是在跑完最小割之后就从S开始把能到的点都标为1
    至于反向弧为什么为1,一是原图无向,二就是为了这个时候能全都遍历到。
    贴代码:
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. const int N=,M=,INF=;
  7. int gi(){
  8. int str=;char ch=getchar();
  9. while(ch>''||ch<'')ch=getchar();
  10. while(ch>=''&&ch<='')str=str*+ch-'',ch=getchar();
  11. return str;
  12. }
  13. int n,m,mark[N];
  14. struct Edge{
  15. int x,y;
  16. }e[M];
  17. bool d[N];bool vis[N];
  18. int num=,head[N],S=,T;
  19. struct Lin{
  20. int next,to,dis;
  21. }a[M*];
  22. void init(int x,int y,int z){
  23. a[++num].next=head[x];
  24. a[num].to=y;
  25. a[num].dis=z;
  26. head[x]=num;
  27. a[++num].next=head[y];
  28. a[num].to=x;
  29. a[num].dis=(z==INF?INF:);
  30. head[y]=num;
  31. }
  32. int q[N],dep[N];
  33. bool bfs()
  34. {
  35. memset(dep,,sizeof(dep));
  36. dep[S]=;q[]=S;int u,x,sum=,t=;
  37. while(t!=sum)
  38. {
  39. x=q[++t];
  40. for(int i=head[x];i;i=a[i].next){
  41. u=a[i].to;
  42. if(dep[u]||a[i].dis<=)continue;
  43. dep[u]=dep[x]+;q[++sum]=u;
  44. }
  45. }
  46. return dep[T];
  47. }
  48. int dfs(int x,int flow)
  49. {
  50. if(x==T || !flow)return flow;
  51. int tmp,sum=,u;
  52. for(int i=head[x];i;i=a[i].next){
  53. u=a[i].to;
  54. if(dep[u]!=dep[x]+ || a[i].dis<=)continue;
  55. tmp=dfs(u,min(flow,a[i].dis));
  56. sum+=tmp;flow-=tmp;
  57. a[i].dis-=tmp;a[i^].dis+=tmp;
  58. if(!flow)break;
  59. }
  60. return sum;
  61. }
  62. void maxflow(){
  63. int tmp;
  64. while(bfs()){
  65. tmp=dfs(S,INF);
  66. while(tmp)tmp=dfs(S,INF);
  67. }
  68. }
  69. void Reset(){
  70. memset(head,,sizeof(head));
  71. memset(vis,,sizeof(vis));
  72. num=;
  73. }
  74. void remark(int x,int pa){
  75. vis[x]=true;
  76. if(!d[x])mark[x]+=pa;
  77. for(int i=head[x];i;i=a[i].next){
  78. if(a[i].dis> && !vis[a[i].to])remark(a[i].to,pa);
  79. }
  80. }
  81. void check(int fx)
  82. {
  83. Reset();
  84. int pa=(<<fx);
  85. for(int i=;i<=n;i++){
  86. if(!d[i])continue;
  87. if(mark[i]&pa)init(S,i,INF);
  88. else init(i,T,INF);
  89. }
  90. for(int i=;i<=m;i++)init(e[i].x,e[i].y,);
  91. maxflow();
  92. remark(S,pa);
  93. }
  94. void work()
  95. {
  96. int pp,x;
  97. n=gi();m=gi();
  98. T=n+;
  99. for(int i=;i<=m;i++)e[i].x=gi(),e[i].y=gi();
  100. pp=gi();
  101. for(int i=;i<=pp;i++)x=gi(),mark[x]=gi(),d[x]=true;
  102. for(int i=;i<=;i++)check(i);
  103. for(int i=;i<=n;i++)printf("%d\n",mark[i]);
  104. }
  105. void Clear(){
  106. memset(mark,,sizeof(mark));
  107. memset(d,,sizeof(d));
  108. }
  109. int main()
  110. {
  111. //freopen("pp.in","r",stdin);
  112. int TT=gi();
  113. while(TT--){
  114. work();
  115. Clear();
  116. }
  117. return ;
  118. }
  1.  
  1.  

【SPOJ839】Optimal Marks 网络流的更多相关文章

  1. [SPOJ839]Optimal Marks

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

  2. SPOJ839 Optimal Marks(最小割)

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

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

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

  4. spoj839 Optimal Marks(最小割,dinic)

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

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

  6. SPOJ OPTM - Optimal Marks

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

  7. SP839 Optimal marks(最小割)

    SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...

  8. Optimal Marks(optimal)

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

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

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

随机推荐

  1. 小草手把手教你 LabVIEW 串口仪器控制——初识VISA串口

    有些人,学习一样东西时候,喜欢现成的例子.很多人学习一门技术,都喜欢现成的例子开始,比如学单片机的啊,最开始都是修改的例子吧,学语言的也是.最开始都是模仿.这个年头看书上的理论知识太浪费时间了.所以啊 ...

  2. java关于for循环。

    众所周知,JAVA中for循环的基本格式为: for(初始化表达式:布尔表达式:循环后更新表达式){循环体} 举个例子来说可以写成 (1)for (int x=1;x<10;x++){ Syst ...

  3. 2017 清北济南考前刷题Day 3 afternoon

    期望得分:100+40+100=240 实际得分:100+40+100=240 将每个联通块的贡献乘起来就是答案 如果一个联通块的边数>点数 ,那么无解 如果边数=点数,那么贡献是 2 如果边数 ...

  4. Raid5两块硬盘掉线可以恢复数据吗_raid数据恢复案例分享

    本案例中发生故障的存储类型是HP P2000,虚拟化平台为vmware exsi,共有10块硬盘组成raid5(硬盘容量为1t,其中6号盘是热备盘),由于某些故障导致阵列中两块硬盘亮黄灯掉线,硬盘无法 ...

  5. faster-rcnn 结构杂谈

    faster-rcnn结构图: (只截取了最难理解的部分) 这个网络看似很复杂,但是理解了其中关键的层,就基本可以掌握这个结构了.要看源码!!要看源码!!要看源码 !!重要的事情说三遍. 关键的层: ...

  6. 遍历JSON

    第一种: each,不做详细说明,太常用了 第二种:我用来遍历单个组,实现前端界面绑定 for(var item in person){ alert("person中"+item+ ...

  7. TP框架关于模版的使用技巧

    1.

  8. 【ASP.NET Core】依赖注入高级玩法——如何注入多个服务实现类

    依赖注入在 ASP.NET Core 中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来.服务类型的实例转由容器自动管理,无需我们在代码中显式处理. 因此,有了依 ...

  9. 我对let和const理解

    ​let和const是es6新出的两种变量声明的方式,接下来我来分别针对这两个,聊一聊. let ​let它的出现,我认为主要是解决了块级作用域的需求.因为js以前本身是没有什么块级作用域的概念的(顶 ...

  10. POJ-1287 Networking---裸的不能再裸的MST

    题目链接: https://vjudge.net/problem/POJ-1287 题目大意: 模板 #include<iostream> #include<cstdio> # ...