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. 常用API - 时间日期类

    Date类 概述 java.util.Date类 表示特定的瞬间,精确到毫秒. 继续查阅Date类的描述,发现Date拥有多个构造函数,只是部分已经过时,但是其中有未过时的构造函数可以把毫秒值转成日期 ...

  2. 线性动归之Wooden Sticks

    题面:现在有n(n<5000)个木头,每个木头都有长度l和重量w(l<10000,w<10000),现在你要对木头进行加工: 1.第一根木头需要先花费1min: 2.加工完第i跟木头 ...

  3. js 整理 前端知识点 前端面试题 (2020)(vue)

    数据类型 字符串(String).数字(Number).布尔(Boolean).对空(Null).未定义(Undefined).Symbol. 引用数据类型:对象(Object).数组(Array). ...

  4. labelImg安装及使用(YOLO标签为例)

    安装: 非常简单. 第一步: cmd中执行 pip install labelImg 我一般会用下面这个 pip install -i https://pypi.tuna.tsinghua.edu.c ...

  5. java 基础(三) 搭建Java编译环境(树莓派)

    安装需求1.JDK的安装2.PI4J的安装 JDK的安装1.首先到JDK的官网:https://www.oracle.com/technetwork/java/javase/downloads/ind ...

  6. 数据可视化之powerBI基础(四)深入了解PowerBI的工具提示功能

    https://zhuanlan.zhihu.com/p/36804592 在PowerBI上个月的更新中,增加了工具提示功能,这项功能允许您将自己的可视化作品放置到工具提示中,通过鼠标悬停的方式来展 ...

  7. 数据可视化之powerBI基础(十八)Power BI度量值的格式如何修改?这里有三种方式

    https://zhuanlan.zhihu.com/p/99818030 ​在知识星球遇到的问题中,有不少朋友问如何修改数值型度量值的格式,比如,新建的度量值如何显示为百分比或者千分位等等,这篇文章 ...

  8. Tomcat的基本使用及相关知识的概述(超详细版)

    絮絮叨叨: 在深入了解Tomcat源码之前,本来是想亲自写一篇Tomcat的基本使用教程的,在网上兜兜转转发现了这篇博客:https://blog.csdn.net/weixin_40396459/a ...

  9. Xamarin.Android调用百度地图

    下载百度地图API Android SDK 在Visual Studio中创建绑定库(Android)项目 将jar文件添加到Jars文件夹中 生成该项目,如果遇到变量名称之类的问题,可在Transf ...

  10. 03-Python控制语句

    一.简介 通过一些语句来改变程序的执行顺序,这些语句被叫做控制语句,在python主要有if.for.while三种控制流语句. 二.if语句 用来检测一个条件是否成立,如果为真,则执行该语句(一般为 ...