https://vjudge.net/problem/SPOJ-OPTM

题意:

给出一个无向图G,每个点 v 以一个有界非负整数 lv 作为标号,每条边e=(u,v)的权w定义为该边的两个端点的标号的异或值,即W=lu XOR lv。现已知其中部分点的标号,求使得该图的总边权和最小的标号赋值。即最小化:

思路:

这道题目在刘伯涛的论文里讲得十分的详细,看看论文就可以啦。

XOR运算是根据二进制的每一位来计算的,,并且因为每一位都是相互独立的,互不影响,所以可以转化为下式:

接下来对于每一位都新建图,对于已经标号的顶点来说,如果该位是1,则与源点相连,否则与汇点相连,容量均为INF。如果本来就相连的点还是需要相连的,容量为1。对于每个还没有标号的点来说,在这一位的取值要么是1,要么是0,这就很符合最小割。在跑完最大流之后,只需要从源点出发,凡是能到达的点都是取值为1的。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = + ; int n, m, k;
int val[maxn];
int ans[maxn];
int vis[maxn];
int mp[maxn][maxn]; struct Edge
{
int from,to,cap,flow;
Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
}; struct Dinic
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int cur[maxn];
int d[maxn]; void init(int n)
{
this->n=n;
for(int i=;i<n;++i) G[i].clear();
edges.clear();
} void AddEdge(int from,int to,int cap)
{
edges.push_back( Edge(from,to,cap,) );
edges.push_back( Edge(to,from,,) );
m=edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS()
{
queue<int> Q;
memset(vis,,sizeof(vis));
vis[s]=true;
d[s]=;
Q.push(s);
while(!Q.empty())
{
int x=Q.front(); Q.pop();
for(int i=;i<G[x].size();++i)
{
Edge& e=edges[G[x][i]];
if(!vis[e.to] && e.cap>e.flow)
{
vis[e.to]=true;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if(x==t || a==) return a;
int flow=, f;
for(int &i=cur[x];i<G[x].size();++i)
{
Edge &e=edges[G[x][i]];
if(d[e.to]==d[x]+ && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>)
{
e.flow +=f;
edges[G[x][i]^].flow -=f;
flow +=f;
a -=f;
if(a==) break;
}
}
return flow;
} int Maxflow(int s,int t)
{
this->s=s; this->t=t;
int flow=;
while(BFS())
{
memset(cur,,sizeof(cur));
flow +=DFS(s,INF);
}
return flow;
}
}DC; void dfs(int u, int x)
{
vis[u]=;
ans[u]+=x;
for(int i=;i<DC.G[u].size();i++)
{
Edge& e=DC.edges[DC.G[u][i]];
if(!vis[e.to] && e.cap>e.flow)
dfs(e.to,x);
}
} void solve()
{
int src=,dst=n+;
int bite=;
while(true)
{
DC.init(dst+);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(mp[i][j]) DC.AddEdge(i,j,); bool flag=false;
for(int i=;i<=n;i++)
{
if(val[i]!=-)
{
if(val[i]>=)
{
flag=true;
}
if(val[i]&)
{
DC.AddEdge(src,i,INF);
}
else
{
DC.AddEdge(i,dst,INF);
}
val[i]>>=;
}
} if(!flag) break;
DC.Maxflow(src,dst);
memset(vis,,sizeof(vis));
dfs(src,bite);
bite<<=;
}
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
memset(mp,,sizeof(mp));
scanf("%d%d",&n,&m);
for(int i=;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
mp[u][v]=mp[v][u]=;
}
memset(val,-,sizeof(val));
scanf("%d",&k);
for(int i=;i<k;i++)
{
int u,v;
scanf("%d%d",&u,&v);
val[u]=v;
}
memset(ans,,sizeof(ans));
solve();
for(int i=;i<=n;i++)
{
printf("%d\n",ans[i]);
}
}
return ;
}

SPOJ 839 Optimal Marks(最小割的应用)的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. BZOJ2400: Spoj 839 Optimal Marks

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

  7. 【BZOJ-2400】Spoj839Optimal Marks 最小割 + DFS

    2400: Spoj 839 Optimal Marks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 567  Solved: 202[Submit ...

  8. 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 ...

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

随机推荐

  1. 设计模式之Facade(外观)(转)

    Facade的定义: 为子系统中的一组接口提供一个一致的界面. Facade一个典型应用就是数据库JDBC的应用,如下例对数据库的操作: public class DBCompare { Connec ...

  2. flask框架----蓝图

    蓝图(flask中多py文件拆分都要用到蓝图) 如果代码非常多,要进行归类.不同的功能放在不同的文件,吧相关的视图函数也放进去.蓝图也就是对flask的目录结构进行分配(应用于小,中型的程序), 小中 ...

  3. 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理(转)

    源: 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理

  4. oracle之存储过程和存储函数的使用和区别

    #存储过程:封装在服务器上一段sql片段,已经编译好了的代码. 1.客户端调存储过程,执行效率就会非常高效. 语法: create [or replace] procedure 存储过程名称 (参数名 ...

  5. 阿里云centos远程连接mysql

    首先在服务器管理控制台设置防火墙规则 添加规则 使用root登录到mysql 添加一个用户名,权限为%的远程连接用户 grant all on *.* to 'yuancheng'@'%' ident ...

  6. Django 事物

    事物 在这里指,将一些关于数据库的一系列操作,打包成一个原子性操作,意思是这一系列操作必须全部执行成功,如果,其中某个操作没有成功,那么这一系列操作都将滚回到之前没执行的状态,包括其中执行成功的某些操 ...

  7. 【题解】Luogu CF86D Powerful array

    原题传送门 裸的莫队啊,我博客里有对莫队较详细的介绍 这道题很简单,可以说是裸的模板 但是如何在已有的值上进行操作? 小学生应该都知道 那么转移就超级简单了qaq inline void add(re ...

  8. 15:element/Vue Admin

    1.1 简介 1.Vue Admin 简介 1. Vue Admin 是一个基于 Vue 2.0 & Bulma 0.3 的后台管理面板(管理系统),相当于是 Vue 版本的 Bootstra ...

  9. 前后台分离开发--文件上传与下载,cookie,session

    一.前后台分离开发的概念 ''' 1. 前台页面运行在前台服务器上,负责页面的渲染(静态文件的加载)与转跳 2. 后台代码运行在后台服务器上,负责数据的处理(提供数据请求的接口) ''' #如果没有前 ...

  10. Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查

    一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...