OPTM-Optimal Marks-SPOJ839最小割
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最小割的更多相关文章
- SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)
http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...
- SP839 Optimal marks(最小割)
SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...
- SPOJ839 Optimal Marks(最小割)
题目大概说给一张图,每个点都有权,边的权等于其两端点权的异或和,现已知几个点的权,为了使所有边的边权和最小,其他点的权值该是多少. 很有意思的一道题,完全看不出和网络流有什么关系. 考虑每个未知的点$ ...
- spoj839 Optimal Marks(最小割,dinic)
题目大意: 给你一个无向图\(G(V,E)\). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记. 对于边\((u,v)\),我们定义\(Cost(u,v)=mark [u]\ ...
- SPOJ 839 Optimal Marks(最小割的应用)
https://vjudge.net/problem/SPOJ-OPTM 题意: 给出一个无向图G,每个点 v 以一个有界非负整数 lv 作为标号,每条边e=(u,v)的权w定义为该边的两个端点的标号 ...
- 【bzoj2400】Spoj 839 Optimal Marks 网络流最小割
题目描述 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其余的点的值由你 ...
- 图论(网络流):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 ...
- Optimal Marks SPOJ - OPTM (按位枚举-最小割)
题意:给一张无向图,每个点有其点权,边(i,j)的cost是\(val_i\ XOR \ val_j\).现在只给出K个点的权值,求如何安排其余的点,使总花费最小. 分析:题目保证权值不超过32位整型 ...
- spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】
因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...
随机推荐
- angularJS实现可编辑的下拉框
将angularJS与插件select2结合使用即可 <!DOCTYPE html><html lang="en"><head> < ...
- float导致父级元素塌陷的问题
利用float进行页面布局时常常会出现父级元素没有高度的塌陷问题,如以下代码: <!DOCTYPE html> <html> <head lang="en&qu ...
- oracle 关键字
Oracle 关键字(保留字) DBA账户下执行SQL语句:select * from v$reserved_words ; 可得到所有的关键字: 1 ! 1 2 & 1 3 ( 1 4 ...
- mysql 在cento下源码安装
虚拟机改为网络地址转换 (NAT) service network restartping www.baidu.com rpm -qa | grep mysql 有的话通过下面的命令来卸载掉 rpm ...
- 【OpenWRT】【RT5350】【二】烧写OpenWrt到RT5350开发板
烧写bin文件到开发板的方式有很多种,我采用的是通过web页面直接上传文件的方式 首先通过浏览器登陆路由器(192.168.1.1),作者的开发板已经烧好了OpenWrt并且可以通过Luci登陆,所以 ...
- kafka windows环境搭建 测试
http://www.cnblogs.com/alvingofast/p/kafka_deployment_on_windows.html 照着例子搭建成功
- SQL优化----百万数据查询优化
百万数据查询优化 1.合理使用索引 索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率.现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构.索引的使用要恰到好处,其使用原则如下: ...
- spark 基本操作
读取文件的数据 使用的数据:https://codeload.github.com/xsankar/fdps-v3/zip/master 读取单个文件的数据 case class Employee(E ...
- 深入理解javascript原型和闭包(1)---一切都是对象
深入理解javascript原型和闭包(1)---一切都是对象 type函数输出的类型,在此列出: function show (x){ console.log(typeof(x));//undefi ...
- ADT(Android Developer Tools) GIT功能不全,远程提交的时候账户密码不能保存账户和密码解决方式
需要安装Eclipse的GIT插件EGIT http://download.eclipse.org/egit/updates/