星屑幻想 optimal mark
LINK :SP839
星屑幻想 取自 OJ 的名称 小事情...题目大意还是要说的这道题比较有意思,想了一段时间。
给你一张图 这张图给答案带来的贡献是每条边上两个点值得异或 一些点的值已经被确定 如何安排剩下的点的权值使答案最小,求在最小答案的基础上那些未标记的点的权值,如果有多组答案取所有星星威力和最小的。
这道题看似很不可做因为 不被确定的点的个数很多 值我们也不好确定 爆搜直接GG。那么怎么办呢?我的思路是:遇到异或 那就是位与位之间的关系了 先考虑拆位。那么我们至少多了一个logn的复杂度了。
考虑现在是一堆点 某些点的当前这位0 1 已经确定我们如何安排剩余的点0还是1使当前这位答案最小呢?(看起来还是一个爆搜...但确实复杂度比刚才低很多但是这不能解决问题。
其实考虑到这里就已经结束了 点的选择只有两个考虑直接网络流,这其实就转化到了使某个点为0/1使和它相连的点的冲突最小(印象中做过这道题
由于要求最小 所以最大流貌似解决不了什么大问题 转最小割 设源点为选1 汇点为选0 那么对于一个未赋值的点来说 既连源点也连汇点。注意这里两个点都未赋值且之间有连边很容易让人想到两个属于同一个集合会带来什么什么样的代价 这时虚设 点 最小割之经典可是在这道题却行不通两个点分属不同的集合才会带来代价。这里可能就不太好想了我们先从简单的来判断 一个未赋值的点和一个点当前这位有确定值的,怎么连边可以体现出来这一点。显然的是如果这个点已被确定为1 那么其连向源点流量INF(确保不被割掉)不连汇点 那么这个确定的和不确定的怎么连边才能体现出来如果分属不同集合的话会带来一些代价呢。
其实画个图观察 发现如果当前未知点选择了0 那么S到它就会被割掉 此时已确定点就要发挥出作用再扣留一个代价了 好了说出做法其实就是已确定点再向未确定点连一条流量为1的边保证这条边也被割掉从而累加代价。
那么考虑两个未知的点的时候吧...关键在此 惊喜的发现和上述方法一样 故本题得到初步的解决最小代价求出来了 那么点的价值相信我们便利残余网络都可以求出吧...
听书上说的话 算法的思维程度远比学几个可以直接来解决问题的数据结构重要。
一个比较重要的点是双向边 问题 这个细节 必须注意 两个未明确的点之间 正反边流量都得是1 这样才能更好的判断出谁是割边当然这对最大流==最小割是没有影响的。
码了大概1h debug 2h 这个最小割有点核心啊,太妙了 被卡的地方是遍历残余网络这一部 我以为可以随便写 yy了一个错误的做法一直不知道怎么改。最正确的做法是这样的:书上提到 割边是这样求出的 从S 开始 遍历然后把所有能到的点给标记 不能到的不标记。这样 标记点到没有标记点之间就是割边了,非常的巧妙。。。 这样我们顺理成章的有了一个做法 可以发现被标记点都是属于S 没被标记的点选择了T 那么 01 自然就划分出来了,我原本的做法是基于点来做的 遍历每个点 与源点之间的连接关系 但是遇到的麻烦是两个未确定的点之间的连边流量是无法快速得出关系的此时必须使用上述的做法 由起点开始标记。
code luogu 多组数据的code 时间复杂度 n^2m*30 看起来稳稳的挂可实际上远远达不到这个上界 所以跑的飞快。
//#include<bits/stdc++.h>
#include<iostream>
#include<ctime>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<utility>
#include<vector>
#include<iomanip>
#include<cstdlib>
#define INF 1000000000
#define min(x,y) ((x)>(y)?(y):(x))
#define max(x,y) ((x)>(y)?(x):(y))
#define db double
#define RE register
#define EPS 1e-8
#define ll long long
#define ull unsigned long long
using namespace std;
char buf[<<],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,,<<,stdin),fs==ft))?:*fs++;
}
inline int read()
{
int x=,f=;char ch=getc();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getc();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getc();}
return x*f;
}
const int MAXN=,maxn=,MAX=MAXN<<;
int G,n,m,k,S,T,maxflow,flow,len,t,h;
int f[maxn],flag[maxn],mark[MAXN];
int lin[MAX],ver[MAX],nex[MAX],e[MAX],q[MAX],vis[MAX];
struct wy{int x,y;}s[MAXN];
inline void add(int x,int y,int z,int z1)
{
ver[++len]=y;nex[len]=lin[x];lin[x]=len;e[len]=z;
ver[++len]=x;nex[len]=lin[y];lin[y]=len;e[len]=z1;
}
inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
inline int bfs()
{
t=h=;
memset(vis,,sizeof(vis));
q[++t]=S;vis[S]=;
while(h++<t)
{
int x=q[h];
for(int i=lin[x];i;i=nex[i])
{
int tn=ver[i];
if(!e[i])continue;
if(vis[tn])continue;
vis[tn]=vis[x]+;
q[++t]=tn;
if(tn==T)return ;
}
}
return ;
}
inline int dinic(int x,int flow)
{
if(x==T)return flow;
int rest=flow,k;
for(int i=lin[x];i&&rest;i=nex[i])
{
int tn=ver[i];
if(vis[tn]==vis[x]+&&e[i])
{
k=dinic(tn,min(e[i],rest));
if(!k){vis[tn]=;continue;}
e[i]-=k;e[i^]+=k;rest-=k;
}
}
return flow-rest;
}
inline void dfs(int x)
{
vis[x]=;
for(int i=lin[x];i;i=nex[i])
{
int tn=ver[i];
if(!e[i])continue;
if(vis[tn])continue;
dfs(tn);
}
}
inline void solve(int p)//处理第p位数字
{
len=;
memset(lin,,sizeof(lin));
for(int i=;i<=n;++i)
{
mark[i]=;
if(flag[i])
{
if(f[i]&(<<p))add(S,i,INF,);//源点为1
else
{
add(i,T,INF,);//汇点为0
mark[i]=;
}
}
else
{
add(S,i,,);
add(i,T,,);
mark[i]=;
}
}
for(int i=;i<=m;++i)
{
int x=s[i].x;
int y=s[i].y;
if(mark[x]==&&mark[y]==){add(x,y,,);continue;}
if(mark[x]==mark[y])continue;
if(mark[x]>mark[y])swap(x,y);
if(mark[x]==&&mark[y]==){add(y,x,,);continue;}
add(x,y,,);
}
flow=maxflow=;
while(bfs())while((flow=dinic(S,INF)))maxflow+=flow;
memset(vis,,sizeof(vis));
dfs(S);
for(int i=;i<=n;++i)
{
if(flag[i])continue;
f[i]=f[i]|(vis[i]<<p);
}
return;
}
int main()
{
freopen("1.in","r",stdin);
G=read();
while(G--)
{
memset(f,,sizeof(f));
memset(flag,,sizeof(flag));
n=read();m=read();
S=n+;T=S+;
for(int i=;i<=m;++i)
{
int x,y;
x=read();y=read();
s[i]=(wy){x,y};
}
k=read();
for(int i=;i<=k;++i)
{
int x,z;
x=read();z=read();
flag[x]=;f[x]=z;
}
for(int i=;i>=;--i)solve(i);
for(int i=;i<=n;++i)printf("%d\n",f[i]);
}
return ;
}
觉得非常自然...
星屑幻想 optimal mark的更多相关文章
- p1349星屑幻想
这道题的原题目我也不知道是什么. 大致题意是有一个图,有些点的权值已确定,要求你确定其他点的权值使所有边两个点的权值的xor和最小,输出所有点的最终权值,输出有spj: 解法是最小割,由于题目要求的使 ...
- JZYZOJ1349 SPOJ839 星屑幻想 xor 网络流 最大流
http://172.20.6.3/Problem_Show.asp?id=1349 调了两个小时发现数组开小了[doge].题意:给出几个点,有的点的权值确定,连接两点的边的权值为两点值的异或和,求 ...
- 图论(网络流):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 ...
- java.io.IOException: mark/reset not supported
java.io.IOException: mark/reset not supported at java.io.InputStream.reset(InputStream.java:348) at ...
- [mark] 使用Sublime Text 2时如何将Tab配置为4个空格
在Mac OS X系统下,Sublime Text是一款比较赞的编辑器. 作为空格党的自觉,今天mark一下使用Sublime Text 2时如何将Tab配置为4个空格: 方法来自以下两个链接: ht ...
- Optimal Flexible Architecture(最优灵活架构)
来自:Oracle® Database Installation Guide 12_c_ Release 1 (12.1) for Linux Oracle base目录命名规范: /pm/s/u 例 ...
随机推荐
- 神奇的建图方式(Tarjan)——小z玩游戏
原题来自与:洛谷 P5676(GZOI2017) 链接: https://www.luogu.com.cn/problem/P5676 题面: 题意比较明显,如果已经建好了边,那么跑个Tarjan ...
- STA树的深度(树型DP)
STA树的深度 题目大意 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. Outpu ...
- P2585 三色二叉树 题解
题目 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序列,我们称之为"二叉树序列S": \[S=\left\{ \begin{aligned} 0 &\ \ 表 ...
- day79 组件化开发
目录 一.组件[component] 默认组件 二. Vue自动化工具(Vue-cli) 1 安装node.js 2 npm 3 安装Vue-cli 4 使用Vue-CLI初始化创建前端项目 4.1 ...
- day57 jQuery基础
目录 一.操作标签 1 位置操作 2 尺寸 3 文本操作 4 获取值操作 5 属性操作 6 获取属性的特例 7 文档处理 二.事件 1 克隆事件 2 自定义模态框 3 左侧菜单 4 回到顶部 5 输入 ...
- day46 作业
# 班级表 create table class( cid int primary key auto_increment, caption char(16) ); # 学生表 create table ...
- 使用Rancher在K8S上部署高性能PHP应用程序
介 绍 PHP是网络上最流行的编程语言之一,许多被广泛使用的内容管理系统都使用它开发,如WordPress和Drupal,并为现代服务器端框架(如Laravel和Symfony)提供核心代码. 尽管P ...
- Mysql基础(十一):Self Join
Summary: 如何使用 MySQL self join 进行表的 自己对自己的join操作.. 前面的教程,已经教过join语法,都是两个表的之间的操作,特殊的,当一个表自己和自己进行join,那 ...
- Java匿名对象介绍
Java匿名对象介绍 什么是匿名对象? 顾名思义就是没有变量名的对象,即创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量. 匿名对象命名格式:以Scanner类举例 new Scann ...
- Mesos+Zookeeper+Marathon+Docker环境搭建
相关理论请参考:https://www.cnblogs.com/Bourbon-tian/p/7155054.html,本文基于https://www.cnblogs.com/Bourbon-tian ...