题目大意

给出一个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)}的最小值和最大值。

无解输出NIE

分析

可以搞出很多对方程组

\(A+B=C\)

\(0\le A \le p_A\)

\(0\le B \le p_B\)

之类的

由于是一幅图

对于每个连通块

我们设其中一个点为x

其它的所有点都可以用kx+b来表示,k为\(\pm1\)

正样我们可以求出x的取值范围

进而求出最大最小值

注意

x空集NIE

如果便利到一个点已经有k和b

1.k相同,b不同,NIE

2.k不同,直接将x的取值范围确定为一个定值

solution

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=500007;
const int M=3000007; inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
} LL mn=0,mx=0;
int n,m;
LL fir[N];
int g[N],te;
struct edge{int y,next;LL d;}e[M<<1]; void addedge(int x,int y,LL d){
e[++te].y=y;e[te].d=d;e[te].next=g[x];g[x]=te;
} int vis[N];
LL k[N],b[N];
LL n_mx,n_mn;
LL n_k,n_b;
int q[N]; void NIE(){
puts("NIE");
exit(0);
} void bfs(int bg){
int h=0,t=1,x,p,y;
LL lf,rt;
LL kk,bb;
q[t]=bg;
vis[bg]=1;
while(h^t){
x=q[++h];
n_k+=k[x];
n_b+=b[x]; if(k[x]==-1) lf=b[x]-fir[x],rt=b[x];
else lf=-b[x],rt=fir[x]-b[x];
if(rt<n_mn) NIE();
if(lf>n_mx) NIE();
if(lf>rt) NIE();
n_mn=max(n_mn,lf);
n_mx=min(n_mx,rt); for(p=g[x];p;p=e[p].next){
y=e[p].y;
if(!vis[y]){
k[y]=-k[x];
b[y]=e[p].d-b[x];
q[++t]=y;
vis[y]=1;
}
else{
kk=-k[x];
bb=e[p].d-b[x];
if(kk==k[y]){
if(bb!=b[y]) NIE();
}
else{
bool rev=0;
if(kk==-1) swap(kk,k[y]),swap(bb,b[y]),rev=1;
if(b[y]-bb<0) NIE();
if((b[y]-bb)&1) NIE();
lf=rt=(b[y]-bb)/2;
if(rt<n_mn) NIE();
if(lf>n_mx) NIE();
if(lf>rt) NIE();
n_mn=max(n_mn,lf);
n_mx=min(n_mx,rt);
if(rev) k[y]=kk,b[y]=bb;
}
}
}
}
} int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("my.out","w",stdout);
#endif int i,x,y,z;
n=rd(),m=rd(); for(i=1;i<=n;i++) fir[i]=rd(); for(i=1;i<=m;i++){
x=rd(),y=rd(),z=rd();
z=fir[x]+fir[y]-z;
addedge(x,y,z);
addedge(y,x,z);
} for(i=1;i<=n;i++)
if(!vis[i]){
n_mn=0;
n_mx=fir[i];
n_k=0;
n_b=0;
k[i]=1;
b[i]=0;
bfs(i);
if(n_k<0){
mn+=n_mx*n_k+n_b;
mx+=n_mn*n_k+n_b;
}
else{
mn+=n_mn*n_k+n_b;
mx+=n_mx*n_k+n_b;
}
}
printf("%lld %lld\n",mn,mx); return 0;
}

bzoj 2801 [Poi2012]Minimalist Security 设一个,求出所有的更多相关文章

  1. 【BZOJ2801】[Poi2012]Minimalist Security BFS

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

  2. bzoj 2797 [Poi2012]Squarks 枚举一个,推出所有

    题目大意 设有n个互不相同的正整数{X1,X2,...Xn},任取两个Xi,Xj(i≠j),能算出Xi+Xj. 现在所有取法共n*(n-1)/2个和,要你求出X1,X2,...Xn. 输出所有满足条件 ...

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

    BZOJ_2801_[Poi2012]Minimalist Security_dfs树+特判+乱搞 Description 给出一个N个顶点.M条边的无向图,边(u,v)有权值w(u,v),顶点i也有 ...

  4. [POI2012] BEZ-Minimalist Security

    一张n个点m条边的无向图,有点权有边权都是非负,且每条边的权值小于等于两个顶点的权值和,现在要将每个点减一个非负整数使得每条边权等于两个顶点的点权和,问最大修改代价和最小修改代价 思路神的一匹,完全想 ...

  5. 一个字符串中可能包含a~z中的多个字符,如有重复,如String data="aavzcadfdsfsdhshgWasdfasdf",求出现次数最多的那个字母及次数,如有多个重复的则都求出。

    主要掌握String中的方法 char[] toCharArray()           将此字符串转换为一个新的字符数组. int indexOf(String str)           返回 ...

  6. 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数。

    描述 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数.   输入 第一行为M,表示测试数据组数.接下来M行,每行包含一个测试数据. 输出 ...

  7. python练习题,写一个方法 传进去列表和预期的value 求出所有变量得取值可能性(例如list为[1,2,3,4,5,6,12,19],value为20,结果是19+1==20只有一种可能性),要求时间复杂度为O(n)

    题目:(来自光荣之路老师)a+b==valuea+b+c=valuea+b+c+d==valuea+b+c+d+...=valuea和b....取值范围都在0-value写一个方法 传进去列表和预期得 ...

  8. 【BZOJ 4555】[Tjoi2016&Heoi2016]求和 多项式求逆/NTT+第二类斯特林数

    出处0.0用到第二类斯特林数的性质,做法好像很多,我打的是直接ntt,由第二类斯特林数的容斥公式可以推出,我们可以对于每一个i,来一次ntt求出他与所有j组成的第二类斯特林数的值,这个时候我们是O(n ...

  9. 黑马基础阶段测试题:定义一个int类型的数组,数组中元素为{5,7,3,9,4}。求出数组中的最小值,并判断最小值是否为偶数,如果是偶数则输出“最小值为偶数”,如果不是偶数则输出“最小值为奇数”。打印如下:

    package com.swift; import java.util.Arrays; public class ArrayTest { public static void main(String[ ...

随机推荐

  1. python 与 json

    +-------------------+---------------+    | Python            | JSON          |    +================= ...

  2. python之函数默认参数的坑

    坑 当你的默认参数如果是可变的数据类型,你要小心了 例题 # 正常没毛病的操作 def func(a,b=False): print(a) print(b) func(1,True) # 在实参角度, ...

  3. Spring学习笔记之Spring概述

    概述   Spring是一个java应用最广的开源框架,它是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Deve ...

  4. rem和em的区别

    原文链接:http://caibaojian.com/rem-vs-em.html rem 单位如何转换为像素值 当使用 rem 单位,他们转化为像素大小取决于页根元素的字体大小,即 html 元素的 ...

  5. matplotlib subplot 子图

    总括 MATLAB和pyplot有当前的图形(figure)和当前的轴(axes)的概念,所有的作图命令都是对当前的对象作用.可以通过gca()获得当前的axes(轴),通过gcf()获得当前的图形( ...

  6. 2829: 高精A+B [1*+]

    题目描述 输入A和B,计算A+B的值 Input 两行数据,分别是A和B 0<=A<=1E200 0<=B<=10^200 Output A+B的结果 Sample Input ...

  7. DNS预解析 dns-prefetch

    1.DNS 是什么? Domain Name System,域名系统,作为域名和IP地址相互映射的一个分布式数据库. DNS大家都懂,那么浏览器访问域名的时候,是需要去解析一次DNS,也就是把域名 g ...

  8. 【php】对象的比较

    对象的比较 相等的比较 ==当使用比较运算符(==)比较两个对象变量时,比较的原则是:如果两个对象的属性和属性值 都相等,而且两个对象是同一个类的实例,那么这两个对象变量相等. 全等的比较 ===如果 ...

  9. 通过源码编译安装VIM

    开发中使用的是Ubuntu 12.04 LTS,通过sudo apt-get install vim安装的版本较低,不支持YCM,所以,用源码编译并安装最新的Vim. 卸载旧版本的Vim: sudo ...

  10. python-函数基础、函数参数

    目录 函数的基础 什么是函数 为何用函数 如何调用函数 定义函数的三种形式 无参函数 有参函数 空函数 函数的返回值 什么是返回值 为什么要有返回值 函数的调用 函数参数的应用 形参和实参 位置参数 ...