本来以为过了...然后FST了...

吐槽:nmdGraph为什么不连通...

这题想法其实非常\(na\ddot{\imath}ve\),就是对于一个连通块先钦点一个点为根,颜色是\(1\),考虑到边权限制点权,可以做二分图染色,钦点连通块内的某个形如树形的边的子集是全部合法的,显然一棵树是一定有解的,对于此时的\(\min ,\max\)只需要看根节点的取值范围取\(\min ,\max\),对于图的话显然就是多了一些边,判断多的边两端节点是否同色,如果同色则意味着根节点的权值是唯一确定的,如果不是整数则无解,否则直接赋值重跑一遍计算\(ans\)即可,复杂度\(\mathcal{O}(n+m)\)。

因为代码是从FST的改过来的,memset其实会T,但是懒得改了,所以下面代码复杂度是假的,不过不影响正确性

#include<bits/stdc++.h>
#define yes printf("%lld %lld\n",ansa,ansb);exit(0)
#define no printf("NIE\n");exit(0)
#define int long long using namespace std; signed ch; void qread(int &xx){
xx=0;ch=getchar();
while(!isdigit(ch)){
ch=getchar();
}
while(isdigit(ch)){
xx=xx*10+ch-'0';
ch=getchar();
}
} const int N=5e5+5,M=6e6+6; int n,m,ans,ansa,ansb,p[N],vis[N]; int fir[N],nxt[M],to[M],edge[M],cntedge,col[N],c[N],cnt[3]; int mi[3]={0,0,0x3f3f3f3f},up[3]={0,0,0x3f3f3f3f}; void addedge(int u,int v,int w){
++cntedge;to[cntedge]=v;edge[cntedge]=w;nxt[cntedge]=fir[u];fir[u]=cntedge;
} namespace subtree{
queue<int>q;
void bfs(int u){
for(int now=fir[u],v;now;now=nxt[now]){
v=to[now];
if(col[v]){
continue;
}
c[v]=edge[now]-c[u];
col[v]=3-col[u];
++cnt[col[v]];
ans+=c[v];
mi[col[v]]=min(mi[col[v]],c[v]);
up[col[v]]=min(up[col[v]],p[v]-c[v]);
q.push(v);
}
}
void solve(){
q.push(1);col[1]=1;++cnt[1];up[1]=p[1];
while(!q.empty()){
int u=q.front();q.pop();
bfs(u);
}
if(up[1]+up[2]<0){
no;
}
if(up[1]<0){
for(int i=1;i<=n;i++){
col[i]==1?(c[i]+=up[1],ans+=up[1]):(c[i]-=up[1],ans-=up[1]);
}
up[2]+=up[1];mi[2]-=up[1];mi[1]+=up[1];up[1]=0;
}
if(up[2]<0){
for(int i=1;i<=n;i++){
col[i]==2?(c[i]+=up[2],ans+=up[2]):(c[i]-=up[2],ans-=up[2]);
}
up[1]+=up[2];mi[1]-=up[2];mi[2]+=up[2];up[2]=0;
}
if(mi[1]+up[2]<0||mi[2]+up[1]<0||mi[1]+mi[2]<0){
no;
}
if(mi[1]<0){
for(int i=1;i<=n;i++){
col[i]==1?c[i]-=mi[1],ans-=mi[1]:c[i]+=mi[1],ans+=mi[1];
}
up[2]+=mi[1];mi[2]+=mi[1];up[1]+=mi[1];mi[1]=0;
}
else if(mi[2]<0){
for(int i=1;i<=n;i++){
col[i]==2?c[i]-=mi[2],ans-=mi[2]:c[i]+=mi[2],ans+=mi[2];
}
up[1]+=mi[2];mi[1]+=mi[2];up[2]+=mi[2];mi[2]=0;
}
if(cnt[1]==cnt[2]){
ansa=ansb=ans;
}
else if(cnt[1]<cnt[2]){
ansa=ans-min(mi[2],up[1])*(cnt[2]-cnt[1]);
ansb=ans+min(mi[1],up[2])*(cnt[2]-cnt[1]);
}
else{
ansa=ans-min(mi[1],up[2])*(cnt[1]-cnt[2]);
ansb=ans+min(mi[2],up[1])*(cnt[1]-cnt[2]);
}
yes;
}
} namespace qwq{
queue<int>q;
int s,id=0;bool flag;
bool check(){
while(!q.empty()){
q.pop();
}
memset(col,0,sizeof col);
q.push(s);col[s]=1;ans=c[s];
while(!q.empty()){
int u=q.front();q.pop();
vis[u]=id;
if(c[u]<0||c[u]>p[u]){
no;
}
for(int now=fir[u],v;now;now=nxt[now]){
v=to[now];
if(col[v]){
if(c[u]+c[v]!=edge[now]){
no;
}
continue;
}
c[v]=edge[now]-c[u];
col[v]=3-col[u];
ans+=c[v];
q.push(v);
}
}
ansa+=ans;ansb+=ans;
return 1;
}
void bfs(int u){
vis[u]=id;
for(int now=fir[u],v;now;now=nxt[now]){
v=to[now];
if(col[v]){
if(col[u]^col[v]){
if(c[u]+c[v]!=edge[now]){
no;
}
}
else{
if(((c[u]+c[v])&1)^(edge[now]&1)){
no;
}
if(col[u]^2){
c[s]=(edge[now]-c[u]-c[v])>>1;
if(check()){
flag=1;return;
}
else{
no;
}
}
else{
c[s]=(c[u]+c[v]-edge[now])>>1;
if(check()){
flag=1;return;
}
else{
no;
}
}
}
continue;
}
c[v]=edge[now]-c[u];
col[v]=3-col[u];
++cnt[col[v]];
ans+=c[v];
mi[col[v]]=min(mi[col[v]],c[v]);
up[col[v]]=min(up[col[v]],p[v]-c[v]);
q.push(v);
}
}
void work(){
while(!q.empty()){
q.pop();
}
flag=0;
memset(cnt,0,sizeof cnt);
up[2]=mi[2]=0x3f3f3f3f;mi[1]=0;
q.push(s);col[s]=1;++cnt[1];up[1]=p[s];ans=0;
while(!q.empty()){
int u=q.front();q.pop();bfs(u);
}
if(flag){
return;
}
if(up[1]+up[2]<0){
no;
}
if(up[1]<0){
for(int i=1;i<=n;i++){
if(vis[i]!=id){
continue;
}
col[i]==1?(c[i]+=up[1],ans+=up[1]):(c[i]-=up[1],ans-=up[1]);
}
up[2]+=up[1];mi[2]-=up[1];mi[1]+=up[1];up[1]=0;
}
if(up[2]<0){
for(int i=1;i<=n;i++){
if(vis[i]!=id){
continue;
}
col[i]==2?(c[i]+=up[2],ans+=up[2]):(c[i]-=up[2],ans-=up[2]);
}
up[1]+=up[2];mi[1]-=up[2];mi[2]+=up[2];up[2]=0;
}
if(mi[1]+up[2]<0||mi[2]+up[1]<0||mi[1]+mi[2]<0){
no;
}
if(mi[1]<0){
for(int i=1;i<=n;i++){
if(vis[i]!=id){
continue;
}
col[i]==1?c[i]-=mi[1],ans-=mi[1]:c[i]+=mi[1],ans+=mi[1];
}
up[2]+=mi[1];mi[2]+=mi[1];up[1]+=mi[1];mi[1]=0;
}
else if(mi[2]<0){
for(int i=1;i<=n;i++){
if(vis[i]!=id){
continue;
}
col[i]==2?c[i]-=mi[2],ans-=mi[2]:c[i]+=mi[2],ans+=mi[2];
}
up[1]+=mi[2];mi[1]+=mi[2];up[2]+=mi[2];mi[2]=0;
}
if(cnt[1]==cnt[2]){
ansa+=ans;ansb+=ans;
}
else if(cnt[1]<cnt[2]){
ansa+=ans-min(mi[2],up[1])*(cnt[2]-cnt[1]);
ansb+=ans+min(mi[1],up[2])*(cnt[2]-cnt[1]);
}
else{
ansa+=ans-min(mi[1],up[2])*(cnt[1]-cnt[2]);
ansb+=ans+min(mi[2],up[1])*(cnt[1]-cnt[2]);
}
}
void solve(){
for(int i=1;i<=n;i++){
if(!vis[i]){
++id;s=i;
work();
}
}
yes;
}
} signed main(){
qread(n);qread(m);
for(int i=1;i<=n;i++){
qread(p[i]);
}
for(int i=1,u,v,w;i<=m;i++){
qread(u);qread(v);qread(w);addedge(u,v,p[u]+p[v]-w);addedge(v,u,p[u]+p[v]-w);
}
if(n==m+1){
subtree::solve();
}
else{
qwq::solve();
}
no;
return 0;
}

noi.ac NA537 【Graph】的更多相关文章

  1. noi.ac NA536 【打地鼠】

    又一道可写的小清新思维题 其实想到倒着做了,然而还是因为T1害人不浅(我太菜了),所以并没有写 考虑两个局面不同,显然至少打了一次地鼠,基于操作的颜色覆盖性质,我们可以考虑把操作倒着做,对于一个X点, ...

  2. noi.ac NA535 【生成树】

    因为太蠢一直写T1也没仔细想,赛后发现是个真小清新思维题,本质构造??? 首先显然不会无解,这个随随便便证一下就有了 另外给的式子没啥意义,也就能说明颜色随机???害人不浅 然后就从\(1\)开始,钦 ...

  3. noi.ac NA534 【猫】

    一眼暴力DP 再一眼决策单调性? 打个表以为是四边形不等式?? 最后发现是斜率优化??? 于是成功写了个假斜率优化真四边形不等式拿了\(80\) 设\(f[i][j]\)表示有\(i\)个工作人员出发 ...

  4. NOI.AC#2007-light【根号分治】

    正题 题目链接:http://noi.ac/problem/2007 题目大意 \(n\)个格子排成一排,每个格子有一个\(0/1\)和一个颜色.开始每个格子都是\(0\),\(q\)次操作取反一个颜 ...

  5. NOI.AC#2266-Bacteria【根号分治,倍增】

    正题 题目链接:http://noi.ac/problem/2266 题目大意 给出\(n\)个点的一棵树,有一些边上有中转站(边长度为\(2\),中间有一个中转站),否则就是边长为\(1\). \( ...

  6. AC日记——【模板】Link Cut Tree 洛谷 P3690

    [模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...

  7. AC日记——【模板】点分治(聪聪可可) 洛谷 P2634

    [模板]点分治(聪聪可可) 思路: 点分治: (感谢灯神) 代码: #include <bits/stdc++.h> using namespace std; #define maxn 2 ...

  8. AC日记——【模板】分块/带修改莫队(数颜色) 洛谷 P1903

    [模板]分块/带修改莫队(数颜色) 思路: 带修改莫队: (伏地膜xxy): 代码: #include <bits/stdc++.h> using namespace std; #defi ...

  9. AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369

    [模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...

随机推荐

  1. Appium-实战之启动App 获取信息说明

    如下为启动 格来云游戏APP启动信息 代码如下: from appium import webdriver caps = {} caps["platformName"] = &qu ...

  2. Ubuntu重启关机命令

    重启命令 :  1.reboot 立刻重启 2.shutdown -r now 立刻重启 3.shutdown -r 10 过10分钟自动重启 4.shutdown -r 20:35 在时间为20:3 ...

  3. webdriervAPI(元素等待)

    from  selenium  import  webdriver from selenium.common.exceptions import NoSuchElementException driv ...

  4. mysql——操作数据库

    一.查看数据库 show databases; 二.创建数据库 create database 数据库名; 三.删除数据库 drop database 数据库名; 四.查看数据库存储引擎 show e ...

  5. win10安装tensorflow (cpu版)

    前提: 下载anaconda,然后创建一个python虚拟环境: 命令: conda create -n tf_cpu python=3.6       # (tf_cpu  是这个虚拟环境的名字) ...

  6. 第三周课程总结&实验报告一

    实验一 Java开发环境与简单Java程序 一.实验目的 熟悉JDK开发环境 熟练掌握结构化程序设计方法 二.实验内容 1.在此处输入标题打印输出所有的"水仙花数",所谓" ...

  7. 【BZOJ4668】冷战(并查集)

    Description 1946 年 3 月 5 日,英国前首相温斯顿·丘吉尔在美国富尔顿发表"铁幕演说",正式拉开了冷战序幕.美国和苏联同为世界上的"超级大国" ...

  8. PTA(Basic Level)1014.福尔摩斯的约会 && PTA(Advanced Level)1061.Dating

    大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm.大侦探很快就明白了,字条上奇 ...

  9. git clone 报错 fatal: protocol '–https' is not supported 解决办法

    版本:git 2.22.0 系统:win7旗舰版 先把https去掉 再把https加上 神奇的事情出现了,这样就可以了. 很多人都说这样解决了,原因不知道. Administrator@BWE8QX ...

  10. Storm本地启动拓扑报错:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/storm/topology/IRichSpout

    问题描述: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/storm/topology ...