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. locust接口压测

    前言: locust是完全基于python,是一个简单易用的分布式负载测试工具 Locust特性 使用Python编写模拟用户行为的代码,无需繁琐的配置 分布式可扩展,能够支持上百万用户 自带Web界 ...

  2. Java工具类之:包装类

    Java工具类--包装类 我们都知道,JDK 其实给我们提供了很多很多 Java 开发者已经写好的现成的类,他们其实都可以理解成工具类,比如我们常见的集合类,日期相关的类,数学相关的类等等,有了这些工 ...

  3. day24 常用模块(下)

    目录 一.logging模块 1 日志级别 2 默认级别为warning,默认打印到终端 3 为logging模块指定全局配置,针对所有的logger有效,控制打印到文件中 4.logging配置文件 ...

  4. day60 django入门

    目录 一.静态文件配置 1 引子 2 如何配置 1 在settins.py中的具体配置 2 静态文件的动态解析(html页面中) 二.request对象方法初识 三.pycharm链接数据库(mysq ...

  5. day39 作业

    实现生产消费原理 from multiprocessing import Process,JoinableQueue import time import random def cooker(q): ...

  6. pytest框架使用教程

    Pytest框架 一.简介 pytest:基于unittest之上的单元测试框架 有什么特点? 自动发现测试模块和测试方法 断言更加方便,assert + 表达式,例如 assert 1 == 1 灵 ...

  7. 根据URL下载图片到本地

    /// <summary> /// 下载图片 /// </summary> /// <param name="picUrl">图片Http地址& ...

  8. Mysql基础(一):Mysql初识、基本指令、数据库密码相关、创建用户及授权

    来源:https://www.cnblogs.com/liubing8/p/11432534.html 目录 数据库01 /Mysql初识.基本指令.数据库密码相关.创建用户及授权 1. 数据库概述 ...

  9. Django框架03 /视图相关

    Django框架03 /视图相关 目录 Django框架03 /视图相关 1. 请求相关 2.响应相关 3.FBV和CBV 视图(视图函数和视图类) 3.1 类视图 CBV 3.2 视图函数 FBV ...

  10. HotSpot VM垃圾收集器

    最常用的HotSpot VM垃圾收集器是分代垃圾收集.该方案是基于两个观察事实. 大多数分配对象的存活时间很短. 存活时间久的对象很少引用存活时间短的对象. 上述两个观察事实统称为弱分代假设(Weak ...