Optimal Marks(optimal)
Optimal Marks(optimal)
题目描述
定义无向图边的值为这条边连接的两个点的点权异或值。
定义无向图的值为无向图中所有边的值的和。
给定nn个点mm条边构成的图。其中有些点的权值是给定的,另外一些由你来定。点权必须为非负数。现在你需要使无向图的值最小,且在保证图的权值最小的情况下点的权值的和最小。
输入
第一行两个数nn和mm,表示图的点数和边数。
接下来nn行,每行一个数,表示每个点的权值。如果是负数,表示该点点权由你定,点权绝对值不超过109109。
接下来mm行,每行两个数aa和bb,表示aa和bb之间有无向边相连。(保证无重边和自环,但不保证是连通图)。
输出
第一行,一个数,表示无向图的最小值。
第二行,一个数,表示此时无向图中点权的和的值。
样例输入
3 2
2
-1
0
1 2
2 3
样例输出
2
2
提示
对于所有数据:
n≤500n≤500 m≤2000m≤2000
样例解释:
将22号点权值定位00即可。
solution
考虑拆位,这样权值就变成了0/1
建图
若w[i]=1
lj(S,i,inf);
若w[i]=0
lj(i,T,inf);
对于原图中的边(u,v)
lj(u,v,1);lj(v,u,1);
然后就是最小割的问题了
割在S表示选1,T表示选0
这样就解决了第一问。
对于第二问,我们要求T集尽量大
由于流量只有0和1,我们可以从S开始遍历,发现0就返回,找出最小的S集
e[i].v打成k调了一下午。。。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define maxn 5005
#define inf 1e9
using namespace std;
int n,m,w[maxn],a1[20002],b1[20002],tot=1,head[maxn],S,T;
int d[maxn],flag[maxn],cur[maxn],ans,fl[maxn];
long long anse,ansv;
struct node{
int v,nex,cap;
}e[100005];
void Q(){
tot=1;
memset(head,0,sizeof head);
}
void lj(int t1,int t2,int t3){
tot++;e[tot].v=t2,e[tot].cap=t3;e[tot].nex=head[t1];head[t1]=tot;
}
bool BFS(){
for(int i=1;i<=T;i++)d[i]=inf,flag[i]=0;
queue<int>q;q.push(S);d[S]=0;
while(!q.empty()){
int x=q.front();q.pop();cur[x]=head[x];
for(int i=head[x];i;i=e[i].nex){
if(d[e[i].v]>d[x]+1&&e[i].cap){
d[e[i].v]=d[x]+1;
if(!flag[e[i].v]){
flag[e[i].v]=1;q.push(e[i].v);
}
}
}
flag[x]=0;
}
return d[T]!=inf;
}
int lian(int k,int a){
//cout<<k<<' '<<a<<endl;
if(k==T||!a)return a;
int f,flow=0;
for(int& i=cur[k];i;i=e[i].nex){
if(d[e[i].v]==d[k]+1&&(f=lian(e[i].v,min(a,e[i].cap)))>0){
flow+=f;a-=f;
e[i].cap-=f;e[i^1].cap+=f;
if(!a)break;
}
}
return flow;
}
void dfs(int k,int fa,int num){
if(w[k]<0){ansv+=(1<<num);}fl[k]=1;
for(int i=head[k];i;i=e[i].nex){
if(e[i].v!=fa){
if(e[i].cap>0&&!fl[e[i].v])dfs(e[i].v,k,num);
}
}
}
int main()
{
cin>>n>>m;S=n+1,T=S+1;
for(int i=1;i<=n;i++){scanf("%d",&w[i]);if(w[i]>0)ansv+=w[i];}
for(int i=1;i<=m;i++)scanf("%d%d",&a1[i],&b1[i]);
for(int ws=30;ws>=0;ws--){
Q();
for(int i=1;i<=n;i++){
if(w[i]<0)continue;
if((w[i]&(1<<ws))>0)lj(S,i,inf),lj(i,S,0);
else lj(i,T,inf),lj(T,i,0);
}
for(int i=1;i<=m;i++){
lj(a1[i],b1[i],1),lj(b1[i],a1[i],0);
lj(a1[i],b1[i],0),lj(b1[i],a1[i],1);
}
ans=0;
while(BFS())ans+=lian(S,inf);
//cout<<ans<<endl;
anse+=1LL*ans*(1<<ws);
memset(fl,0,sizeof fl);
dfs(S,0,ws);
}
printf("%lld\n%lld\n",anse,ansv);
return 0;
}
Optimal Marks(optimal)的更多相关文章
- 图论(网络流):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 ...
- SP839 Optimal marks(最小割)
SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...
- [SPOJ839]Optimal Marks
[SPOJ839]Optimal Marks 试题描述 You are given an undirected graph \(G(V, E)\). Each vertex has a mark wh ...
- 【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 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...
- 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 ...
- 【SPOJ839】Optimal Marks 网络流
You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range ...
- BZOJ2400: Spoj 839 Optimal Marks
Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其 ...
随机推荐
- pytho线程信号量
pytho线程信号量 import threading,time def going(num,sleep_time): semaphore.acquire()#启动允许执行 print("g ...
- 使用Scanner类获取键盘输入的会员卡号,并将该数据存储在变量中,输出这个变量的信息
package come.one01;import java.util.Scanner; // 导入Scanner类public class One03 { public static void ma ...
- Repeater控件里面取不到CheckBox的值
然后在后台需要取到,选中了那些 然后在后台怎么取也取不到,当时就纳闷了,然后开始怀疑自己的代码是不是错了,经过仔细一看,我的妈呀,加载事件了差一句话......整个人都不好了 加载事件差这句话不行,补 ...
- AngularJS 应用
AngularJS模块(Module)定义了AngularJS的应用. AngularJS控制器(Controller)用于控制AngularJS应用. ng-app指令定义了应用,ng-contro ...
- question 002: dev c++ 当中如何调整字体大小?How to get the first program with C++? c++属于什么软件?
方法:按住ctrl+鼠标滑轮滚动 c++属于系统软件还是应用软件? 说哪个都不对,编译之前属于应用软件,after compile ,it belongs to system software. #i ...
- 处理侧滑返回与 ScrollView 手势冲突
与处理双击.单击手势互斥原则一样: // 手势互斥(侧滑返回手势失效后才响应UITableView的滑动手势) [tableView.panGestureRecognizer requireGestu ...
- let和const在es6中的异同点
let和const这两个都是声明一个变量或函数的方法与var差不太多的效果 let的声明在for循环中,当你定义的是多少,最后你的值就是多少开始的,它只进行一次循环,不会像var那样去一遍一遍的去遍历 ...
- Zabbix监控告警Lack of free swap space on Zabbix server解决办法
报错详情如下: 是因为Zabbix监控没有考虑虚拟主机的交换空间情况 解决办法修改配置 修改表达式内容:{Template OS Linux:system.swap.size[,pfree].last ...
- 初学puppet
初学puppet puppet是什么? puppet是一个开源的软件自动化配置和部署工具,很多大型IT公司均在使用puppet对集群中的软件进行管理和部署. Puppet简介 Puppet的目录是让管 ...
- LOL游戏基本代码
class Hero: def __init__(self, new_nickname, new_aggressivity, new_life_value, new_money, new_armor ...