题目链接:戳我

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

然后我们考虑对于每一个联通块,首先任意确定一个点,给它设最终值为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. cef chromium 编译

    前言 目前客户端引用了cef sharp库来嵌入web页面 cef sharp是对cef (chromium embed framework)的c#封装 cef是对chromium内核的c++封装 什 ...

  2. 题解 UVA1316 【Supermarket】

    题目链接: https://www.luogu.org/problemnew/show/UVA1316 思路: 根据题目意思,我们需要用到贪心的思想,越晚过期的商品当然是越晚卖好.同时你假如有多个商品 ...

  3. O060、Restore Volume 操作

    参考https://www.cnblogs.com/CloudMan6/p/5668872.html   前面我们学习了backup操作,现在我们来学习如何使用backup进行restore.   r ...

  4. LeetCode:595.大的国家

    题目链接:https://leetcode-cn.com/problems/big-countries/ 题目 这里有张 World 表 +-----------------+------------ ...

  5. jmeter压测实践

    技巧一:命令行执行 命令执行:指定参数,报告的存储位置 jmeter -n -t baidu_requests_results.jmx -r -l baidu_requests_results.jtl ...

  6. vue使用scss应该安装哪些依赖

    通过vue-cli搭建的项目如果想使用scss的话除了安装sass-loader,还需要安装node-sass cnpm install sass-loader node-sass -D

  7. Python 之 random模块

    Python中的random模块用于生成随机数.1.random.random()  #用于生成一个0到1的随机浮点数:0<= n < 1.0>>> random.ran ...

  8. (转)JVM垃圾回收机制

    一.技术背景 GC的历史比Java久远,早在1960年Lisp这门语言中就使用了内存动态分配和垃圾回收技术 二.那些内存需要回收? JVM的内存结构包括五大区域:程序计数器.虚拟机栈.本地方法栈.堆区 ...

  9. Tomcat----服务运行的容器

    在介绍Tomcat之前,我们先介绍一个概念Servlet. Servlet是一个运行在WEB服务器上的小的Java程序,用来接收和响应从客户端发送过来的请求,通常使用HTTP协议.从下图可以看出Ser ...

  10. contextlib:上下文管理器工具

    介绍 contextlib模块包含的工具可以用于处理上下文管理器和with语句 上下文管理器API ''' 上下文管理器(context manager)负责管理一个代码块中的资源,会在进入代码块时创 ...