BZOJ_2801_[Poi2012]Minimalist Security_dfs树+特判+乱搞

Description

给出一个N个顶点、M条边的无向图,边(u,v)有权值w(u,v),顶点i也有权值p(i),
并且对于每条边(u,v)都满足p(u)+p(v)>=w(u,v)。
现在要将顶点i的权值减去z(i),其中0<=z(i)<=p(i)。
修改后设顶点i的权值p'(i)=p(i)-z(i),对于每条边(u,v)都满足p'(u)+p'(v)=w(u,v)。
求sum{z(i)}的最小值和最大值。

Input

第一行两个正整数n,m (n<=500,000, m<=3,000,000)。
第二行n个整数,依次表示p(1),p(2),...,p(n) (0<=p(i)<=10^6)。
下面m行,每行三个整数u,v,w (1<=u,v<=n, 0<=w<=10^6),表示存在一条权值为w的边(u,v)。

Output

两个正整数,分别表示sum{z(i)}的最小值和最大值,如果不存在方案就输出NIE。

Sample Input

For the input data:
3 2
5 10 5
1 2 5
2 3 3
the correct result is:
12 15
whereas for the following input data:
3 3
1 1 1
1 2 1
1 3 1
3 2 1
the correct result is:
NIE

考虑每个联通块,只有确定一个的值就能全部确定。
只考虑树上的边,然后给根一个权值0判非树边合法的做法是对的吗?
如果图中只有偶环这个做法是对的,并且在此基础上我们能求出根节点每增加一整棵树是加还是减。
同时确定每条边的范围(最少根节点要加几和最多根节点能加几),然后答案就能确定。
现在有了奇环,有什么影响?
考虑两个端点是同时加减的,也就是不能染色判非树边无解。
但反过来考虑,我们知道了这两个端点的和,同时因为同加减,两个端点的差也确定了,直接可以确定这两个点。
 
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
typedef long long ll;
#define N 500050
#define M 3000050
#define GG puts("FUCK")
int cnt,n,m,head[N],to[M<<1],nxt[M<<1],val[M<<1],a[N];
int Q[N],l,r,L[N],R[N],b[N],c[N],vis[N],dep[N],qwq[N],d[N],S[N],ls,rs;
inline char nc() {
static char buf[100000],*p1,*p2;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
int rd() {
int x=0; char s=nc();
while(s<'0'||s>'9') s=nc();
while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
return x;
}
inline void add(int u,int v,int w) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
}
int ok;
ll ans1,ans2,suma,sumb,s1,s2;
int lmax,rmin;
void dfs(int x) {
int i; vis[x]=1;
suma+=a[x]; sumb+=b[x];
if(!c[x]) L[x]=(b[x]>=0?0:-b[x]),R[x]=a[x]-b[x];
else L[x]=(b[x]<=a[x]?0:b[x]-a[x]),R[x]=b[x];
lmax=max(lmax,L[x]);
rmin=min(rmin,R[x]);
if((b[x]<0&&c[x])||(b[x]>a[x]&&!c[x])) {
puts("NIE"); exit(0);
}
c[x]?s2++:s1++;
for(i=head[x];i;i=nxt[i]) {
int y=to[i];
if(ok) return ;
if(!vis[y]) {
dep[y]=dep[x]+1;
b[y]=val[i]-b[x]; c[y]=c[x]^1;
dfs(y);
}else {
if((dep[x]-dep[y])%2) {
// printf("%d %d\n",dep[x],dep[y]);
if(b[y]+b[x]!=val[i]) {
puts("NIE"); exit(0);
}
}else {
// GG;
ok=1;
if((b[x]-b[y]+val[i])&1) {
puts("NIE"); exit(0);
}
// printf("%d %d\n",x,y);
if(qwq[x]&&d[x]!=(b[x]-b[y]+val[i])/2) {
puts("NIE"); exit(0);
}
d[x]=(b[x]-b[y]+val[i])/2;
if(qwq[y]&&d[y]!=val[i]-d[x]) {
puts("NIE"); exit(0);
}
d[y]=val[i]-d[x];
// printf("%d %d\n",d[x],d[y]);
if(!qwq[x]) S[rs++]=x;
if(!qwq[y]) S[rs++]=y;
qwq[x]=qwq[y]=1;
return ;
}
}
}
}
void bfs(int s) {
int i,x;
l=r=0;
s1=0,s2=0;
suma=0,sumb=0;
Q[r++]=s;
b[s]=0; c[s]=0; L[s]=0; R[s]=a[s];
lmax=0,rmin=1<<30,ok=0;
rs=ls=0;
dfs(s);
if(ok) {
suma=0;
int i;
ll sumd=0;
while(ls<rs) {
x=S[ls++]; sumd+=d[x]; suma+=a[x]; qwq[x]=1;
if(d[x]<0||d[x]>a[x]) {
puts("NIE"); exit(0);
}
for(i=head[x];i;i=nxt[i]) {
if(!qwq[to[i]]) {
qwq[to[i]]=1;
S[rs++]=to[i];
d[to[i]]=val[i]-d[x];
}else if(d[x]+d[to[i]]!=val[i]) {
puts("NIE"); exit(0);
}
}
}
ans1+=suma-sumd;
ans2+=suma-sumd;
return ;
}
if(lmax>rmin) {
puts("NIE"); exit(0);
}
if(s1>s2) {
ans1+=suma-sumb-ll(s1-s2)*lmax;
ans2+=suma-sumb-ll(s1-s2)*rmin;
}else {
ans1+=suma-sumb-ll(s1-s2)*rmin;
ans2+=suma-sumb-ll(s1-s2)*lmax;
}
}
int main() {
// freopen("C.in","r",stdin);
// freopen("C.out","w",stdout);
n=rd(); m=rd();
// if(n==20&&m==53) {
// puts("NIE"); return 0;
// }
// if(n==20&&m==54) {
// puts("NIE"); return 0;
// }
// if(n==20&&m==56) {
// puts("NIE"); return 0;
// }
int i,x,y,z;
for(i=1;i<=n;i++) a[i]=rd();
for(i=1;i<=m;i++) {
x=rd(); y=rd(); z=rd();
add(x,y,z); add(y,x,z);
}
for(i=1;i<=n;i++)
if(!vis[i]&&!qwq[i])
bfs(i);
printf("%lld %lld\n",ans2,ans1);
}

BZOJ_2801_[Poi2012]Minimalist Security_dfs树+特判+乱搞的更多相关文章

  1. Codeforces 1182D Complete Mirror 树的重心乱搞 / 树的直径 / 拓扑排序

    题意:给你一颗树,问这颗树是否存在一个根,使得对于任意两点,如果它们到根的距离相同,那么它们的度必须相等. 思路1:树的重心乱搞 根据样例发现,树的重心可能是答案,所以我们可以先判断一下树的重心可不可 ...

  2. Luogu3732 [HAOI2017] 供给侧改革 【后缀数组】【线段树】【乱搞】

    题目分析: 这道题我是乱搞的,因为他说$01$串是随机的. 那么我们可以猜测能够让LCP变大的地方很少.求出后缀数组之后可能让LCP变大的地方就等价于从大到小往height里动态加点同时维护这个点左右 ...

  3. [CSP-S模拟测试]:统计(树状数组+乱搞)

    题目传送门(内部题120) 输入格式 第一行,两个正整数$n,m$. 第二行,$n$个正整数$a_1,a_2,...,a_n$,保证$1\leqslant a_i\leqslant n$,可能存在相同 ...

  4. BZOJ 1012: [JSOI2008]最大数maxnumber 单调队列/线段树/树状数组/乱搞

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 4750  Solved: 2145[Submi ...

  5. 【BZOJ2801】[Poi2012]Minimalist Security BFS

    [BZOJ2801][Poi2012]Minimalist Security Description 给出一个N个顶点.M条边的无向图,边(u,v)有权值w(u,v),顶点i也有权值p(i),并且对于 ...

  6. BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞

    看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...

  7. [bzoj1067][SCOI2007]降雨量——线段树+乱搞

    题目大意 传送门 题解 我国古代有一句俗话. 骗分出奇迹,乱搞最神奇! 这句话在这道题上得到了鲜明的体现. 我的方法就是魔改版线段树,乱搞搞一下,首先借鉴了黄学长的建树方法,直接用一个节点维护年份的区 ...

  8. “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛题解&&源码【A,水,B,水,C,水,D,快速幂,E,优先队列,F,暴力,G,贪心+排序,H,STL乱搞,I,尼姆博弈,J,差分dp,K,二分+排序,L,矩阵快速幂,M,线段树区间更新+Lazy思想,N,超级快速幂+扩展欧里几德,O,BFS】

    黑白图像直方图 发布时间: 2017年7月9日 18:30   最后更新: 2017年7月10日 21:08   时间限制: 1000ms   内存限制: 128M 描述 在一个矩形的灰度图像上,每个 ...

  9. 直径上的乱搞 bzoj1999求树直径上的结点+单调队列,bzoj1912负权树求直径+求直径边

    直径上的乱搞一般要求出这条直径上的点集或者边集 bzoj1999:对直径上的点集进行操作 /* 给出一颗树,在树的直径上截取长度不超过s的路径 定义点u到s的距离为u到s的最短路径长度 定义s的偏心距 ...

随机推荐

  1. 使用Lua 局部变量来优化性能,同一时候比較局部变量和全局变量

    在竞争激烈的游戏行业中,尤其页游,面对策划复杂和频繁的需求,使用脚本能够减少难度和成本.在使用Lua的过程中,会常常訪问全局变量来作为配置文件. 在訪问全局变量时,能够通过局部变量引用全局变量来优化. ...

  2. 江湖问题研究-- intent传递有没有限制大小,是多少?

    出门一步,便是江湖.江湖上有很多流言. 比方这条: intent传递是有限制大小的,详细在40KB左右. 当然也有传言说是1M左右. 数百头母驴为何半夜慘叫? 小卖部安全套为何屡遭黑手? 女生宿舍内裤 ...

  3. Windows下编程2----- C语言常用函数举例

    几个小函数 1.    //MessageBoxA(0,"网络故障,重新登录","qq error",3); //弹出对话框 2.    //ShellExec ...

  4. oracle [union.minus.intersect]

    union 两张表的相同字段的数据[记录类型和列数要一致],合并,并且去重 can replace with "in" (但是如果是两个不同的表而且没什么关联的话必须要union了 ...

  5. ANDROID STUDIO 2.2.3 DOWNLOAD FROM DL.GOOGLE.COM

    立即开始使用 Android Studio Android Studio 包含用于构建 Android 应用所需的所有工具. 下载 ANDROID STUDIO2.2.3 FOR WINDOWS (1 ...

  6. 新一代AJAX API:FETCH

    AJAX半遮半掩的底层API是饱受诟病的一件事情. XMLHttpRequest 并不是专为Ajax而设计的. 虽然各种框架对 XHR 的封装已经足够好用, 但我们可以做得更好.更好用的API是 fe ...

  7. SQLMAP源码分析(一)

    说起来,学习Python很大一部分原因是由于对WEB安全的兴趣以及对SQLMAP这款工具的好奇,曾经设想学完Python基础就读一读SQLMAP源码,然而懒病一犯,随之就大江东去.近来,又重新燃起了读 ...

  8. NTAG 标签

    NTAG 标签 这里描述针对 NTAG213.而 NTAG215/216只是容量不同,其它功能都一样.  UID UID 有 7 bytes.上图中有 9 bytes 的 serial number ...

  9. FFmpeg解码详细流程

    FFmpeg在解码一个视频的时候的函数调用流程.为了保证结构清晰,其中仅列出了最关键的函数,剔除了其它不是特别重要的函数. 下面解释一下图中关键标记的含义. 函数背景色 函数在图中以方框的形式表现出来 ...

  10. Linux 操作系统中的进程结构

    前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系.依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 ...