星屑幻想 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 例 ...
随机推荐
- Django---进阶2
目录 数据的查,改,删 django orm中如何创建表关系 django请求生命周期流程图(必会) 路由层 路由匹配 无名分组 有名分组 无名有名是否可以混合使用 反向解析 作业 数据的查,改,删 ...
- 数据可视化之DAX篇(十四)DAX函数:RELATED和RELATEDTABLE
https://zhuanlan.zhihu.com/p/64421378 Excel中知名度最高的函数当属VLOOKUP,它的确很有用,可以在两个表之间进行匹配数据,使工作效率大大提升,虽然它也有很 ...
- 数据可视化之DAX篇(十二)掌握时间智能函数,同比环比各种比,轻松搞定!
https://zhuanlan.zhihu.com/p/55841964 时间可以说是数据分析中最常用的独立变量,工作中也常常会遇到对时间数据的对比分析.假设要计算上年同期的销量,在PowerBI中 ...
- 数据可视化之分析篇(一)使用Power BI进行动态帕累托分析
https://zhuanlan.zhihu.com/p/57763423 通过简单的点击交互,就能进行动态分析发现见解,才是我们需要的,恰好这也是 PowerBI 所擅长的. 就帕累托分析来说,能从 ...
- Show information of directory or disk
There are so many commands of Ubuntu, we just need to know useful and high-frequency commands. I hav ...
- 微信小程序开发部署
一.开发准备 1,想要开发微信小程序,必须要有一个AppId,如果没有可以去注册一个. https://mp.weixin.qq.com/进入注册页面,点击上方注册. 2,点击选择“小程序”出 ...
- 线性dp 之 奶牛渡河
题目描述 Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏. 由于奶牛不会划船,在整个渡河过程中,FJ必须始终在木 ...
- CSS3伪元素 ::first-letter ::first-line ::selection
首先,关于伪元素的语法: 有的时候单冒号也能用,但最好写双冒号. 伪类:匹配的是元素(不同状态或结构的). 伪元素:匹配的是元素中的一部分内容(首字符,首行文本). ::first-letter 匹配 ...
- NCRE-Python考点
NCRE-Python考点 作者:封亚飞本文不含 文件处理.面向对象程序设计.公共基础.计算生态希望各位可以批评指正Qq 64761294 由于图片上传不方便,需要真题的朋友可以加我的qq找我要pdf ...
- 题解 洛谷 P4695 【[PA2017]Banany】
考虑用动态点分治来解决像本题这样带修的树上路径问题. 首先对原树进行点分治,建出点分树,在点分树每个节点上用动态开点线段树来维护以该节点为起点,到其点分树子树中每个节点的利润. 查询时只需在点分树上当 ...