Spoj 839 Optimal Marks

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 908  Solved: 347
[Submit][Status][Discuss]

Description

定义无向图中的一条边的值为:这条边连接的两个点的值的异或值。
定义一个无向图的值为:这个无向图所有边的值的和。
给你一个有n个结点m条边的无向图。其中的一些点的值是给定的,而其余的点的值由你决定(但要求均为非负数),使得这个无向图的值最小。在无向图的值最小的前提下,使得无向图中所有点的值的和最小。
 

Input

第一行,两个数n,m,表示图的点数和边数。
接下来n行,每行一个数,按编号给出每个点的值(若为负数则表示这个点的值由你决定,值的绝对值大小不超过10^9)。
接下来m行,每行二个数a,b,表示编号为a与b的两点间连一条边。(保证无重边与自环。)
 

Output

    第一行,一个数,表示无向图的值。
    第二行,一个数,表示无向图中所有点的值的和。
 

Sample Input

3 2
2
-1
0
1 2
2 3

Sample Output

2
2

HINT

数据约定

n<=500,m<=2000

样例解释

2结点的值定为0即可。

因为是xor,可以从按位的思考

这种两个答案的,二维偏序差不多,一般会想到费用流,

但是这里可以是图的权值扩大到点权和到达不了的状态,即不由点权和影响。

这样/mx 为图的权值,%mx为点的权和。

然后考虑建图,设S为0集合,T为1集合,所以只需要考虑边两个端点一个选S,一个选T这样才会产生值。

看限制了,如果当前这位有值,那么就按这个赋值,如果是1,那么S-i为inf,i-T为1;

这样的,边的话,就是10000的边。

具体看代码。

每次的最大流的意义不同,代表1<<i。

 #include<cstring>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue> #define inf 1000000007
#define ll long long
#define N 507
#define M 20007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if (ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,S,T;
int num[N];
int cnt,hed[N],nxt[M],rea[M],val[M],cur[N];
int dis[N];
ll ans1,ans2;
struct Node
{
int x,y;
}a[M]; void add(int u,int v,int w)
{
nxt[++cnt]=hed[u];
hed[u]=cnt;
rea[cnt]=v;
val[cnt]=w;
}
void add_two_edge(int u,int v,int w)
{
add(u,v,w);
add(v,u,);
}
void build(int x)
{
memset(hed,-,sizeof(hed)),cnt=;
for (int i=;i<=n;i++)
if (num[i]<) add_two_edge(i,T,);
else
{
if (num[i]&(<<x))add_two_edge(S,i,inf),add_two_edge(i,T,);
else add_two_edge(i,T,inf);
}
for (int i=;i<=m;i++)
add_two_edge(a[i].x,a[i].y,),
add_two_edge(a[i].y,a[i].x,);
}
bool bfs()
{
for (int i=S;i<=T;i++)dis[i]=-;
dis[S]=;
queue<int>q;q.push(S);
while(!q.empty())
{
int u=q.front();q.pop();
for (int i=hed[u];i!=-;i=nxt[i])
{
int v=rea[i],fee=val[i];
if (dis[v]!=-||!fee)continue;
dis[v]=dis[u]+;
if (v==T)return ;
q.push(v);
}
}
return ;
}
ll dfs(int u,int MX)
{
ll res=;
if (MX==||u==T)return MX;
for (int i=cur[u];i!=-;i=nxt[i])
{
int v=rea[i],fee=val[i];
if (dis[v]!=dis[u]+)continue;
int x=dfs(v,min(MX,fee));
cur[u]=i,res+=x,MX-=x;
val[i]-=x,val[i^]+=x;
if (MX==) break;
}
if (!res)dis[u]=-;
return res;
}
ll dinic()
{
ll res=;
while(bfs())
{
for (int i=S;i<=T;i++)cur[i]=hed[i];
res+=dfs(,inf);
}
return res;
}
int main()
{
n=read(),m=read(),S=,T=n+;int mx=-;
for (int i=;i<=n;i++)
{
num[i]=read();
mx=max(mx,num[i]);
}
for (int i=;i<=m;i++)a[i].x=read(),a[i].y=read();
for (int i=;(<<i)<=mx;i++)
{
build(i);
ll res=dinic();
ans1+=(res/)*(ll)(<<i);
ans2+=(res%)*(ll)(<<i);
}
printf("%lld\n%lld\n",ans1,ans2);
}

【bzoj2400】Spoj 839 Optimal Marks 按位最大流的更多相关文章

  1. BZOJ2400: Spoj 839 Optimal Marks

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. java编程基础——二叉树的镜像

    题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 题目代码 /** * @program: JavaCode * @description: 操作给定的二叉树,将其变换为源二叉树的镜像. * 二 ...

  2. java基础面试题:java中有没有goto? 在JAVA中如何跳出当前的多重嵌套循环?

    goto是Java的保留关键字,但是从来没有直接使用到goto,goto的跳转作用在Java中受到了限制,只有在特定场合下才能使用,如while for等循环中用continue.break或结合标签 ...

  3. AngularJS1.X版本双向绑定九问

    前言 由于工作的原因,使用angular1.x版本已经有一段时间了,虽然angualr2升级后就完全重构了,但每个版本存在也有一定的道理.话不多说,进入正题. 1.双向绑定的原理是什么? Angual ...

  4. 16.2--Jenkins+Maven+Gitlab+Tomcat 自动化构建打包、部署

    分类: Linux服务篇,Linux架构篇   一.环境需求 本帖针对的是Linux环境,Windows或其他系统也可借鉴.具体只讲述Jenkins配置以及整个流程的实现. 1.JDK(或JRE)及J ...

  5. 二十三、MySQL 事务

    MySQL 事务 MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数 ...

  6. ES6 的解构赋值前每次都创建一个对象吗?会加重 GC 的负担吗?

    本文来源于知乎上的一个提问. 为了程序的易读性,我们会使用 ES6 的解构赋值: function f({a,b}){} f({a:1,b:2}); 这个例子的函数调用中,会真的产生一个对象吗?如果会 ...

  7. 课时5.什么是URL(理解)

    其实浏览器的地址栏中输入的地址就是一个URL. http://127.0.0.1/index.html(浏览器会自动添加:80) http://127.0.0.1:80/index.html(这是浏览 ...

  8. JZOJ 5793. 【NOIP2008模拟】小S练跑步

    5793. [NOIP2008模拟]小S练跑步 (File IO): input:run.in output:run.out Time Limits: 2000 ms  Memory Limits:  ...

  9. Visual Studio的下载安装

    下载地址: 下载Visual Studio Code https://code.visualstudio.com/ 安装扩展包 安装图标 View->Extensions 搜索Icon 安装Ma ...

  10. BFS:HDU3085-Nightmare Ⅱ(双向BFS)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) Tot ...