SPOJ OPTM - Optimal Marks
OPTM - Optimal Marks
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
Select Code
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=3e4+5;
const int M=1e6+5;
struct edge{int v,next,cap;}e[M];int tot=1,head[N];
int mark[N],ans[N],dis[N],q[N*10];bool vis[N];
int cas,n,m,k,S,T,a[N][2];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void add(int x,int y,int z1,int z2=0){
e[++tot].v=y;e[tot].cap=z1;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].cap=z2;e[tot].next=head[y];head[y]=tot;
}
inline bool bfs(){
for(int i=S;i<=T;i++) dis[i]=-1;
int h=0,t=1;q[t]=S;dis[S]=0;
while(h!=t){
int x=q[++h];
for(int i=head[x];i;i=e[i].next){
if(e[i].cap&&dis[e[i].v]==-1){
dis[e[i].v]=dis[x]+1;
if(e[i].v==T) return 1;
q[++t]=e[i].v;
}
}
}
return 0;
}
int dfs(int x,int f){
if(x==T) return f;
int used=0,t;
for(int i=head[x];i;i=e[i].next){
if(e[i].cap&&dis[e[i].v]==dis[x]+1){
t=dfs(e[i].v,min(e[i].cap,f));
e[i].cap-=t;e[i^1].cap+=t;
used+=t;f-=t;
if(!f) return used;
}
}
if(!used) dis[x]=-1;
return used;
}
inline int dinic(){
int res=0;
while(bfs()) res+=dfs(S,2e9);
return res;
}
void init(){
n=read();m=read();S=0;T=n+1;
memset(mark,-1,n+1<<2);
for(int i=1;i<=m;i++) a[i][0]=read(),a[i][1]=read();
k=read();
for(int i=1,x,y;i<=k;i++) x=read(),y=read(),mark[x]=y;
}
void DFS(int x,int d){
vis[x]=1;
ans[x]+=d;
for(int i=head[x];i;i=e[i].next){
if(!vis[e[i].v]&&e[i].cap){
DFS(e[i].v,d);
}
}
}
void work(){
memset(ans,0,n+1<<2);
int bite=1;
for(;;){
tot=1;memset(head,0,n+2<<2);
for(int i=1;i<=m;i++) add(a[i][0],a[i][1],1,1);
bool flag=0;
for(int i=1;i<=n;i++){
if(~mark[i]){
if(mark[i]>=1) flag=1;
if(mark[i]&1){
add(S,i,2e9);
}
else{
add(i,T,2e9);
}
mark[i]>>=1;
}
}
if(!flag) break;
dinic();
memset(vis,0,sizeof vis);
DFS(S,bite);bite<<=1;
}
for(int i=1;i<=n;i++) printf("%d ",ans[i]);putchar('\n');
}
int main(){
cas=read();
while(cas--) init(),work();
return 0;
}
SPOJ OPTM - Optimal Marks的更多相关文章
- 图论(网络流):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 ...
- 【bzoj2400】Spoj 839 Optimal Marks 按位最大流
Spoj 839 Optimal Marks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 908 Solved: 347[Submit][Stat ...
- 【BZOJ2400】Spoj 839 Optimal Marks 最小割
[BZOJ2400]Spoj 839 Optimal Marks Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...
- SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)
http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...
- spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】
因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...
- BZOJ2400: Spoj 839 Optimal Marks
Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其 ...
- spoj 839 Optimal Marks(二进制位,最小割)
[题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17875 [题意] 给定一个图,图的权定义为边的两端点相抑或值的 ...
- SPOJ839 OPTM - Optimal Marks
传送门 闵神讲网络流应用的例题,来水一水 要写出这道题,需要深入理解两个概念,异或和最小割. 异或具有相对独立性,所以我们把每一位拆开来看,即做大概$32$次最小割.然后累加即可. 然后是最小割把一张 ...
- SPOJ 839 Optimal Marks(最小割的应用)
https://vjudge.net/problem/SPOJ-OPTM 题意: 给出一个无向图G,每个点 v 以一个有界非负整数 lv 作为标号,每条边e=(u,v)的权w定义为该边的两个端点的标号 ...
随机推荐
- Python-装饰器进阶
基本概念 具体概念请先看之前的文章 理解装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理, Web权限校验, Cache等. 很有名的例子,就 ...
- Shell 脚本修改 Mac IP地址
本篇文章由:http://xinpure.com/shell-script-to-modify-the-mac-ip-address/ 麻烦事 最近在笔记本 WIFI 网络上遇到一个麻烦事, 在公司需 ...
- python hello wlord
入门运行第一个python程序 https://www.python.org/ 官网下载最新python3安装到电脑 安装成功 cmd进入到安装目录 1.在cmd中直接进入到python安装目录 编写 ...
- 数据库表syscolumns 各个字段含义 select * from syscolumns where name='textA'
每个数据库创建后都会有一些系统表用来存储该数据库的一些基本信息 每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行.该表位于每个数据库中. 列名 数据类型 描述 name sysna ...
- vue TypeError: Cannot read property 'length' of undefined 问题解决思路
上图中是我在接手一个项目的时候,出现的一个关于数组的 bug,但是从上图来看,其实报错是不清楚的,只能从报错信息上看出来是 /src/page/waybill/waybill_form.vue 这个 ...
- Mongodb - TTL(time to live)特性
TTL集合支持mongodb对存储的数据进行失效时间设置,经过指定的时间段后.或在指定的时间点过期,集合自动被mongod清除.这一特性有利于对一些只需要保存一定时间的数据信息进行存储,比如机器产生的 ...
- php.ini配置与中国间隔12小时间设置方法
打开php.ini 配置文件找到date.timezone把=号后面的参数改成这个date.timezone = Etc/GMT+4即可,这样与中国的时间误差即能达到12小时
- Python 函数常用方法总结
一.函数的定义与优势: 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率. Python提供了许多内建函数,比如print(),但也可以自己 ...
- PLS-00157: AUTHID only allowed on schema-level programs解决办法 包体的过程使用调用者权限方法
在包体里写了一个过程,test执行时报错,但是如果把该过程单独拿出来创建一个,就能顺利执行. 在没加上调用者权 authid current_user之前,报错如下 ORA-01031: insuf ...
- jsp中跳出循环
<c:otherwise> <c:set var="flag" value="true" /><!-- 设置flag --> ...