题目链接:戳我

首先注意这张图有可能不连通!!

然后我们考虑对于每一个联通块,首先任意确定一个点,给它设最终值为x,然后进行搜索。(因为对于一个联通块而言,我们知道一个点的最终值,那么整个联通块上面点的值就都知道了)

我们发现这些值只有-x+b或者x+b两种情况。

当一个点被访问到了第二次,如果两次x的系数一样且b不一样,就可以直接输出NIE。如果系数不一样,那么也就可以确认x的大小了(之后记得还要检验一下子)。

如果没有点被访问两次或者以上,那么就是一些不等式的限制条件,我们直接解不等式就行啦。而总数的极值一定也在x的极值上QAQ

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<ctime>
#define MAXN 500010
#define MAXM 3000010
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
return x*f;
}
int n,m,t,cnt,tot;
int head[MAXN],p[MAXN],done[MAXN],col[MAXN],vec[MAXN];
long long minn_ans,maxx_ans;
struct Node{int k,b;}node[MAXN];
struct Edge{int nxt,to,dis;}edge[MAXM<<1];
inline void add(int from,int to,int dis)
{
edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis;
head[from]=t;
}
inline void calc(int x,int cur_ans)
{
if(cur_ans)
{
for(int i=1;i<=tot;i++)
{
int now=vec[i];
int sum=node[now].k*cur_ans+node[now].b;
if(sum<0||sum>p[now])
{
printf("NIE\n");
exit(0);
}
else
{
minn_ans+=p[now]-sum;
maxx_ans+=p[now]-sum;
}
}
}
else
{
int l=0,r=0x3f3f3f3f;
for(int i=1;i<=tot;i++)
{
int now=vec[i];
if(node[now].k==-1)
{
l=max(l,node[now].b-p[now]);
r=min(r,node[now].b);
}
else
{
l=max(l,-node[now].b);
r=min(r,p[now]-node[now].b);
}
if(l>r)
{
printf("NIE\n");
exit(0);
}
}
long long cur_ans1=0,cur_ans2=0;
for(int i=1;i<=tot;i++)
{
int now=vec[i];
cur_ans1+=p[now]-node[now].k*l-node[now].b;
cur_ans2+=p[now]-node[now].k*r-node[now].b;
}
minn_ans+=min(cur_ans1,cur_ans2);
maxx_ans+=max(cur_ans1,cur_ans2);
}
return;
}
inline void paint(int x,int color)
{
tot=0;
int cur_ans=0;
queue<int>q;
q.push(x);
node[x]=(Node){1,0};
while(!q.empty())
{
if((double)clock()/CLOCKS_PER_SEC>1.8)
{
printf("NIE\n");
exit(0);
}
int u=q.front();q.pop();
if(!col[u]) vec[++tot]=u;
col[u]=color;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
int v_k=(node[u].k==1)?-1:1;
int v_b=edge[i].dis-node[u].b;
if(!col[v])
{
node[v]=(Node){v_k,v_b};
q.push(v);
continue;
}
if(col[v]==color)
{
if(node[v].k==v_k&&node[v].b!=v_b)
{
printf("NIE\n");
exit(0);
}
if(node[v].k!=v_k)
{
int cur=(node[v].b-v_b)/(v_k-node[v].k);
if(cur*(v_k-node[v].k)!=(node[v].b-v_b))
{
printf("NIE\n");
exit(0);
}
if(!cur_ans) cur_ans=cur;
else if(cur_ans!=cur)
{
printf("NIE\n");
exit(0);
}
}
}
}
}
calc(x,cur_ans);
return;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
n=read(),m=read();
for(int i=1;i<=n;i++) p[i]=read();
for(int i=1;i<=m;i++)
{
int x=read(),y=read(),w=read();
add(x,y,w),add(y,x,w);
}
for(int i=1;i<=n;i++)
{
if(!col[i])
cnt++,paint(i,cnt);
}
printf("%lld %lld\n",minn_ans,maxx_ans);
return 0;
}

POI2012 BEZ-Minimalist Security | noi.ac #537 Graph的更多相关文章

  1. 【BZOJ2801】[Poi2012]Minimalist Security BFS

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

  2. # NOI.AC省选赛 第五场T1 子集,与&最大值

    NOI.AC省选赛 第五场T1 A. Mas的童年 题目链接 http://noi.ac/problem/309 思路 0x00 \(n^2\)的暴力挺简单的. ans=max(ans,xor[j-1 ...

  3. NOI.ac #31 MST DP、哈希

    题目传送门:http://noi.ac/problem/31 一道思路好题考虑模拟$Kruskal$的加边方式,然后能够发现非最小生成树边只能在一个已经由边权更小的边连成的连通块中,而树边一定会让两个 ...

  4. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  5. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  6. NOI.AC NOIP模拟赛 第二场 补记

    NOI.AC NOIP模拟赛 第二场 补记 palindrome 题目大意: 同[CEOI2017]Palindromic Partitions string 同[TC11326]Impossible ...

  7. NOI.AC NOIP模拟赛 第一场 补记

    NOI.AC NOIP模拟赛 第一场 补记 candy 题目大意: 有两个超市,每个超市有\(n(n\le10^5)\)个糖,每个糖\(W\)元.每颗糖有一个愉悦度,其中,第一家商店中的第\(i\)颗 ...

  8. NOI.AC NOIP模拟赛 第四场 补记

    NOI.AC NOIP模拟赛 第四场 补记 子图 题目大意: 一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图.删去第\(i\)条边需要\ ...

  9. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

随机推荐

  1. iproute2使用及网络名称空间

    创建一个网络名称空间: 相当于创建一个完全隔离的新网络环境,这个环境包括一个独立的网卡空间,路由表,ARP表,ip地址表,iptables,ebtables,等等.总之,与网络有关的组件都是独立的. ...

  2. JavaScript的几种循环方式

    JavaScript提供了许多通过LOOPS迭代的方法.本教程解释了现代JAVASCRIPT中各种各样的循环可能性 目录: for forEach do...while while for...in ...

  3. Java函数式接口

    函数式接口定义且只定义了一个抽象方法.函数式接口的抽象方法的签名称为函数描述符.Java 8的java.util.function包中引入了几个新的函数式接口. 1.Predicate java.ut ...

  4. python3.3.2中的关键字(转)

    The following identifiers are used as reserved words, or keywords of the language, and cannot be use ...

  5. O026、Nova组件详解

    参考https://www.cnblogs.com/CloudMan6/p/5436855.html   本节开始,我们将详细讲解 Nova 的各个子服务.   前面架构概览一节知道 Nova 有若干 ...

  6. hive用户自定义函数

    一.UDF 1.显示所有函数:show functions ; 2.显示指定函数的帮助:$hive>desc function current_database(); 3. 什么是 UDF? 当 ...

  7. 不错的abap技术网站

    http://www.saptechnical.com/index.htm https://sapcodes.com/

  8. lumen时区

    今天用 Lumen 框架写代码时, 也是初次体验 Lumen, 遇到了一个问题, 从数据库里查出的时间比数据库里保存的 TIMESTAMP 时间慢了8个小时, 很明显这是一个时区设置的问题, 本以为可 ...

  9. navicat连接阿里云mysql

    1.服务器控制台在安全组配置3306端口 2.进入 /etc/ssh/sshd_config 在最下面 加入下面代码 KexAlgorithms diffie-hellman-group1-sha1, ...

  10. MySQL8.x msi版安装教程

    一.下载MySQL 官网下载地址 https://dev.mysql.com/downloads/windows/installer/8.0.html  下载第二个即可(虽然只有32位的 但是会同时安 ...