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. gulp安装+一个超简单入门小demo

    gulp安装參考.gulp安装參考2. 一.NPM npm是node.js的包管理工具.主要功能是管理.更新.搜索.公布node的包. Gulp是通过npm安装的. 所以首先,须要安装node.js. ...

  2. 拦截器及 Spring MVC 整合

    一.实验介绍 1.1 实验内容 本节课程主要利用 Spring MVC 框架实现拦截器以及 Spring MVC 框架的整合. 1.2 实验知识点 Spring MVC 框架 拦截器 1.3 实验环境 ...

  3. NHibernate剖析:Mapping篇之Mapping-By-Code(1):概览

    ModelMapper概述 NHibernate3.2版本号集成Mapping-By-Code(代码映射),其设计思想来源于ConfORM.代码总体构思基于"Loquacious" ...

  4. Eclipse出现&quot;Running Android Lint has encountered a problem&quot;解决方式

    近期打开Eclipse的时候,总是发生这种一个错误:"Running Android Lint has encountered a problem".截图例如以下: . 可是Ecl ...

  5. adb命令具体解释(二)——手机缺失sqlite3时操作数据库的多种解决方式

    在android应用开发无处不在SQLite数据库的身影.那么在开发中怎么使用adb命令操作数据库的功能呢? 以下我们将完整的介绍与数据库操作相关的命令集及当手机缺少sqlite3的时候的多种解决方式 ...

  6. linux系列之-—04 自动删除n天前日志【转】

    让Linux系统定时清理一些不需要的文件,日志很有必要 1. 删除文件命令: find 对应目录 -mtime +天数 -name "文件名" -exec rm -rf {} \; ...

  7. Android与服务器端数据交互(基于SOAP协议整合android+webservice)

    http://www.cnblogs.com/zhangdongzi/archive/2011/04/19/2020688.html 上一节中我们通过http协议,采用HttpClient向服务器端a ...

  8. impdp因致命错误终止 ORA-7445 [kpodpals]

    基本要素 前天好不easy成功给用户把数据全库导出,今天用户又告知导出的数据无法导入,首先就问用户有什么错误提示,给我的回答是就一个'作业"SYSTEM"."SYS_IM ...

  9. kubectl技巧之查看资源列表,资源版本和资源schema配置

    系列目录 在kubernetes里,pod,service,rs,rc,deploy,resource等对象都需要使用yaml文件来创建,很多时候我们都是参照照官方示例或者一些第三方示例来编写yaml ...

  10. linux关机命令详解(转载)

    在linux下一些常用的关机/重启命令有shutdown.halt.reboot.及init,它们都可以达到重启系统的目的,但每个命令的内部工作过程是不同的. Linux centos重启命令: 1. ...