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的更多相关文章

  1. p1349星屑幻想

    这道题的原题目我也不知道是什么. 大致题意是有一个图,有些点的权值已确定,要求你确定其他点的权值使所有边两个点的权值的xor和最小,输出所有点的最终权值,输出有spj: 解法是最小割,由于题目要求的使 ...

  2. JZYZOJ1349 SPOJ839 星屑幻想 xor 网络流 最大流

    http://172.20.6.3/Problem_Show.asp?id=1349 调了两个小时发现数组开小了[doge].题意:给出几个点,有的点的权值确定,连接两点的边的权值为两点值的异或和,求 ...

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

  4. SPOJ OPTM - Optimal Marks

    OPTM - Optimal Marks no tags  You are given an undirected graph G(V, E). Each vertex has a mark whic ...

  5. SP839 Optimal marks(最小割)

    SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...

  6. [SPOJ839]Optimal Marks

    [SPOJ839]Optimal Marks 试题描述 You are given an undirected graph \(G(V, E)\). Each vertex has a mark wh ...

  7. java.io.IOException: mark/reset not supported

    java.io.IOException: mark/reset not supported at java.io.InputStream.reset(InputStream.java:348) at ...

  8. [mark] 使用Sublime Text 2时如何将Tab配置为4个空格

    在Mac OS X系统下,Sublime Text是一款比较赞的编辑器. 作为空格党的自觉,今天mark一下使用Sublime Text 2时如何将Tab配置为4个空格: 方法来自以下两个链接: ht ...

  9. Optimal Flexible Architecture(最优灵活架构)

    来自:Oracle® Database Installation Guide 12_c_ Release 1 (12.1) for Linux Oracle base目录命名规范: /pm/s/u 例 ...

随机推荐

  1. OldTrafford after 102 days

    THE RED GO MARCHING ON   One Team One Love Through the highs and the lows   One hundred and two long ...

  2. HNOI 2014 米特运输(图论)

    HNOI 2014 米特运输 题目大意 给一棵树,每个点有自己的权值,要求更改一些点的权值,使得整棵树满足两个条件: 同一个父亲的所有子节点权值相同 父节点的取值为所有子节点的和 答案输出最少要更改的 ...

  3. 【MySQL】Merge Index导致死锁

    水稻:最近有个朋友生产环境出现MySQL死锁问题,一听是死锁,那必须去看看啊,于是饶(si)有(qu)兴(huo)致(lai)的研究了好几天 菜瓜:MySQL死锁,赶紧分享一下 水稻:能否先让我装完X ...

  4. 还能这么玩?用VsCode画类图、流程图、时序图、状态图...不要太爽!

    文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 软件设计中,有好几种图需要画,比如流程图.类图.组件图等,我知道大部分 ...

  5. sql 增加修改表格属性字段

    1.修改字段默认值 alter table 表名 drop constraint 约束名字 ------注解:删除表的字段的原有约束 alter table 表名 add constraint 约束名 ...

  6. DVWA学习记录 PartⅤ

    File Upload 1. 题目 File Upload,即文件上传漏洞,通常是由于对上传文件的类型.内容没有进行严格的过滤.检查,使得攻击者可以通过上传木马获取服务器的webshell权限,因此文 ...

  7. JVM 专题二:虚拟机(二)Java虚拟机

    2.1 什么是Java虚拟机? Java虚拟机是一台执行字节码的虚拟计算机,它拥有独立的运行机制,其运行的Java字节码也未必由Java语言编译而成. JVM平台的各种语言可以共享Java虚拟机带来的 ...

  8. scrapy 基础组件专题(五):自定义扩展

    通过scrapy提供的扩展功能, 我们可以编写一些自定义的功能, 插入到scrapy的机制中 一.编写一个简单的扩展 我们现在编写一个扩展, 统计一共获取到的item的条数我们可以新建一个extens ...

  9. 机器学习实战基础(十三):sklearn中的数据预处理和特征工程(六)特征选择 feature_selection 简介

    当数据预处理完成后,我们就要开始进行特征工程了. 在做特征选择之前,有三件非常重要的事:跟数据提供者开会!跟数据提供者开会!跟数据提供者开会!一定要抓住给你提供数据的人,尤其是理解业务和数据含义的人, ...

  10. Python之爬虫(二十四) 爬虫与反爬虫大战

    爬虫与发爬虫的厮杀,一方为了拿到数据,一方为了防止爬虫拿到数据,谁是最后的赢家? 重新理解爬虫中的一些概念 爬虫:自动获取网站数据的程序反爬虫:使用技术手段防止爬虫程序爬取数据误伤:反爬虫技术将普通用 ...