题目链接:戳我

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

然后我们考虑对于每一个联通块,首先任意确定一个点,给它设最终值为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. Java IO与NIO的总结、比较

    一.IO流总结 1.Java I/O主要包括如下3层次: 流式部分——最主要的部分.如:OutputStream.InputStream.Writer.Reader等 非流式部分——如:File类.R ...

  2. vs2017 不能加载.vdproj

    需要添加Microsoft Visual Studio Installer Projects扩展  下载地址:https://marketplace.visualstudio.com/items?it ...

  3. Python(六) —— 网络请求

    接口调用 接口调用有几个模块可以用:urllib 和 requests ,urllib 是内置的模块,极其不好用,强烈推荐用 requests 模块 get 请求 1.普通的 get 请求 impor ...

  4. opencv3.3.1 + win64 + contrib + cuda 编译

    一 . opencv3.3.1  + win64 + contrib + cuda   编译 1.下载各种依赖 下载安装cuda  https://developer.nvidia.com/cuda- ...

  5. 7 java 笔记

    1 方法是类或者对象行为特征的抽象,方法是类或对象最重要的组成部分 2 java里面方法的参数传递方式只有一种:值传递 值传递:就是将实际参数值的复制品传入方法内,而参数本身不会受到任何影响.(这是j ...

  6. vue项目使用qrcodejs2生成二维码

    最近写项目遇到一个需求,根据后台给的地址生成二维码,在网上找了下,qrcodejs2使用还是比较多,试了下也能实现需求,就整理下使用方法,方便以后使用   1. 安装包 cnpm i qrcodejs ...

  7. https和http的post发送总结

    本文为转贴内容,感谢作者阿进! 需要转发数据到客户的https的服务器上出现一系列问题总结如下: 1.因为是https首先考虑到用最新的控件NetHTTPClient(只有在XE8以上才有). 2.客 ...

  8. C#中UDP(Socket)

    1 使用无连接的套接字,我们能够在自我包含的数据包里发送消息,采用独立的读函数读取消息,读取的消息是使用独立的发送函数发送的.但是UDP数据包不能保证可靠传输,存在许多的因素,比如网络繁忙等等,都有可 ...

  9. 【转】草根老师的 linux字符设备驱动详解

    Linux 驱动 之 模块化编程 Linux 驱动之模块参数和符号导出 Linux 设备驱动之字符设备(一) Linux 设备驱动之字符设备(二) Linux 设备驱动之字符设备(三)

  10. Ubuntu 16.04 装机后如何永久更改ulimit和修改MySQL的存储路径datadir

    Ubuntu 16.04 装机后的配置要点: 1. 网络的配置 2. 更改源列表 3. 永久更改ulimit ulimit限制着程序打开文件的数目,默认情况下为1024,作为服务器使用时,这个数字往往 ...