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

Input:

1

3 2

1 2

2 3

2

1 5

3 100

Output:

5

4

100

在Amber的最小割论文上看到的一道题。





考虑到是异或运算求最小cost之和,由于对于二进制,各个位之间是互不影响的,所以可以将问题转会为每个二进制位的求解,然后求和即可。对于每个二进制位,要么为0,要么为1, 就想到将整个图切割成两个点

集,即对于每个点,都只有两种取值,可以看成是要将点集划分成两类。在这种分类思想的指导下,重新考察操作的意义:对于边的两个端点,若它们同类则边权无值;若它们异类则边权有值1。

建一源点S,汇点T

对于已经标号过的点:

1. 对于位为1的点建边 < S, V, INF, 0>

2. 对于位为0的点建边 < V, T, INF, 0>

对于所有的原边

建成流量为1的双向边< u, v, 1, 1>

这样求得最小割,即为当前位的最优解。

这样建边,求最小割时,保证了割边都是原边,求完后,所有与S相连的点可以标号为1, 所有与T相连的边标号为0, 那么这些割边即为相邻点异类的边,同时保证了他们的和最小。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; const int MaxN = 550; const int MaxM = 3100; typedef struct node
{
int u,v;
}Point; typedef struct Node
{
int v,next,cap;
}edge ; Point a[MaxM]; edge e[MaxM*10]; int mark[MaxN],vis[MaxN],Ans[MaxN]; int H[MaxN]; int n,m,k,s,t,top; void AddEdge(int u,int v,int w1,int w2)
{
e[top].v = v; e[top].cap = w1; e[top].next = H[u]; H[u]= top++; e[top].v = u; e[top].cap = w2; e[top].next = H[v]; H[v] = top++;
} bool BFS()
{
memset(vis,0,sizeof(vis)); queue<int>Q; vis[s] = 1; Q.push(s); while(!Q.empty())
{
int u =Q.front(); Q.pop(); for(int i=H[u];~i;i=e[i].next)
{
if(e[i].cap>0&&!vis[e[i].v])
{
vis[e[i].v] = vis[u]+1; Q.push(e[i].v);
}
}
} return vis[t];
} int DFS(int u,int cap)
{
if(u==t)
{
return cap;
} int ans = 0; for(int i=H[u];~i;i=e[i].next)
{
if(e[i].cap>0&&vis[e[i].v]==vis[u]+1)
{
int ant = DFS(e[i].v,min(e[i].cap,cap)); ans += ant; cap -= ant; e[i].cap-=ant; e[i^1].cap+=ant; if(cap==0)
{
break;
}
}
} return ans;
} void Dinic()
{
while(BFS())
{
DFS(s,INF);
}
} void dfs(int u,int bite)
{
vis[u] = 1; Ans[u]+=bite; for(int i = H[u];i!=-1;i=e[i].next)//和S相连都为1
{
if(e[i].cap>0&&!vis[e[i].v])
{
dfs(e[i].v,bite);
}
}
}
void Solve()
{
int bite=1; memset(Ans,0,sizeof(Ans)); while(1)
{
top = 0; memset(H,-1,sizeof(H)); for(int i=1;i<=m;i++)
{
AddEdge(a[i].u,a[i].v,1,1);
} bool flag=false; for(int i=1;i<=n;i++) //以每一位求一次最小割
{
if(mark[i]!=-1)
{
if(mark[i]>=1)
{
flag=true;
}
if(mark[i]%2)
{
AddEdge(s,i,INF,0);
}
else
{
AddEdge(i,t,INF,0);
} mark[i]>>=1;
}
} if(!flag)//都为零的时候算法结束
{
break;
} Dinic(); memset(vis,0,sizeof(vis)); dfs(s,bite); bite<<=1;
} for(int i=1;i<=n;i++)
{
if(i!=1) printf(" "); printf("%d",Ans[i]);
}
puts("");
} int main()
{
int T; scanf("%d",&T); int u,v,w; while(T--)
{
scanf("%d %d",&n,&m); s=0,t=n+1; for(int i=1;i<=m;i++) scanf("%d %d",&a[i].u,&a[i].v); scanf("%d",&k); memset(mark,-1,sizeof(mark)); for(int i=1;i<=k;i++)
{
scanf("%d %d",&u,&w); mark[u] = w;
} Solve();
}
return 0;
}

OPTM-Optimal Marks-SPOJ839最小割的更多相关文章

  1. SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)

    http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...

  2. SP839 Optimal marks(最小割)

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

  3. SPOJ839 Optimal Marks(最小割)

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

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

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

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

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

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

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

  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. Optimal Marks SPOJ - OPTM (按位枚举-最小割)

    题意:给一张无向图,每个点有其点权,边(i,j)的cost是\(val_i\ XOR \ val_j\).现在只给出K个点的权值,求如何安排其余的点,使总花费最小. 分析:题目保证权值不超过32位整型 ...

  10. spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】

    因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...

随机推荐

  1. Java 获取汉字拼音的方法

    package lius.util;   import java.io.Serializable; import java.util.ArrayList;   public class JString ...

  2. HTML第二本书学习后记

    1,换行标记<br>,不换行标记<nobr></nobr> 2,添加水平线 <hr> 3,插入特殊符号:   空格 &nbsp    " ...

  3. 启动Hive时出现的问题

    Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to i ...

  4. Spring的JDBC框架

    转自: http://www.cnblogs.com/windlaughing/p/3287750.html Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发. Spring主要 ...

  5. tomcat底层原理实现

    1.首先完成一个server类,用来接收客户端的请求:代码都在一个while(true)循环中,模拟tomcat一直在启动,其中绑定一个端口,用来监听一个端口,然后创建一个输入流,获取请求的输入流,然 ...

  6. 来杯Caffe——在ubuntu下安装Caffe框架并测试

    Caffe是一种深度学习框架...blablabla...... Caffe要在ubuntu下安装 1. 安装依赖 sudo apt-get install libatlas-base-dev sud ...

  7. spring cloud的主要组成部分

    服务发现:Eureka断路器: Hystrix 客户端和控制面板客户端负载均衡: Ribbon声明式REST客户端: Feign外部化配置: Archaius路由和过滤器: Zuul RxJava w ...

  8. [Android Tips] 22. Available Java 7 Features in Android

    This only allows Java 7 language features, and you can hardly benefit from anything since a half of ...

  9. VitualBox环境下,实现windows系统与虚拟机Linux文件互传

    本次环境是Win7系统和ubuntu14(虚拟机) 1.首先需要安装VitualBox的增强功能,如图所示 2.安装完成后重启linux系统,然后在WIN7系统下创建共享文件夹(本文在D盘下创建名为V ...

  10. Chrome console命令整理

    console.dir (这个方法是我经常使用的 可不知道比for in方便了多少) 直接将该DOM结点以DOM树的结构进行输出,可以详细查对象的方法发展等等 在页面右击选择 审查元素 ,然后在弹出来 ...