构造一张有向图$G=([1,n],\{(a_{i},b_{i})\})$(可以有重边和自环),定义其连通块为将其看作无向图(即边无向)后分为若干个连通块

记$in_{i}$为$i$的入度(即最终盒子中球的数量)、$out_{i}$为$i$的出度(即初始盒子中球的数量),对于$in_{i}=0$的点,若$out_{i}>0$则一定无解(因为不可能使一个盒子变空),否则$in_{i}=out_{i}=0$,可以直接删除

在此基础上,考虑当$c_{i}=1$的情况,结论:无解当且仅当这张图中存在一个连通块使得其中所有点$out_{i}\le 1$且不是自环

充分性:若$out_{i}\le 1$即不能对其操作,因此需要另取一个点过来才能操作,而这个点还需要至少一次移动回原来的连通块(若不存在这样的点同样无解),因此无解

(不能是自环是因为自环不需要操作)

必要性:首先自环一定可以(不需要操作),那么必然存在一个点$x$满足$out_{x}\ge 2$

考虑当一个盒子内被移动进一个球以后, 由于$c_{i}=1$,因此这个球必然直至结束都在这里,那么对于这个位置上其他的球,可以任意移动到别的位置,重复此过程,即其能到达的所有点的球都移动完毕

将其求强连通分量,构成一张强连通分量的DAG,对于其中入度为0的强连通分量,必然存在一个点$x$满足$out_{x}\ge 2$,证明如下:

反证法,即所有点$out_{x}\le 1$,不考虑其到其他强连通分量的边后仍满足此条件,同时还有$in_{x}\ge 1$,因为其他强连通分量没有到此强连通分量的入边(入度为0)

令该强连通分量点集为$V$,由于$in_{x}\ge 1$,因此$\sum_{x\in V}out_{x}=\sum_{x\in V}in_{x}\ge |V|$,类似的又因为$out_{x}\le 1$,因此必然恰好取$|V|$,即有$in_{x}=out_{x}=1$

此时必然没有其他出边(否则$out_{x}\ge 2$),同时也没有入边,即这就是整个连通块,而不存在$out_{x}\ge 2$,与假设矛盾

选出这样的点$x$,先将其移动到强连通分量内的一点(若只有一个点$x$必然有$x$的自环,否则$x$必然能走到其余点,因此有强连通分量内的出边),根据最初结论,即可以移动到所有能到达的强连通分量(包括自身)

由于所有入度为0的强连通分量都可以选择,即能够覆盖整张图

判定完无解后,由于每一个数恰好移动一次,答案为$\sum [a_{i}\ne b_{i}]$(当$c_{i}=1$时)

接下来考虑$c_{i}$任意的情况,将所有连通块分为三类:

1.所有点出度不超过1且不是自环,这类点需要别的连通块提供1个点帮助其移动,之后其自身也可以对其他1类的连通块提供点

2.存在点出度超过1,这类点可以帮助$\sum (c_{i}-1)$个1类的连通块,需要$t$的额外代价($t$为帮助的连通块数量),特别的,若该边为自环,需要1的额外代价,因为其本来不需要移动

3.自环(指整个连通块是自环),这一类点可以帮助$c_{i}-2$个1类的连通块,需要$t+2$的额外代价

由于$\sum t$是一个常数,我们仅考虑启用第二类中的自环以及第三类的额外代价

特判第一次操作后(只能是第二类,若不存在即为-1),之后的操作都是任意的,先将非自环的用光,对于剩下的两类,同一类中显然从大到小操作,枚举个数+二分即可(可以利用单调性做到线性,但排序仍有log)

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define oo 0x3f3f3f3f
5 vector<long long>v1,v2;
6 int n,m,s,ans,a[N],b[N],c[N],in[N],out[N],f[N],sz[N],vis[N];
7 long long sum;
8 bool cmp(int x,int y){
9 return x>y;
10 }
11 int find1(int x){
12 if (x<=0)return 0;
13 if ((!v1.size())||(v1.back()<x))return oo;
14 return lower_bound(v1.begin(),v1.end(),x)-v1.begin()+1;
15 }
16 int find2(int x){
17 if (x<=0)return 0;
18 if ((!v2.size())||(v2.back()<x))return oo;
19 return lower_bound(v2.begin(),v2.end(),x)-v2.begin()+1;
20 }
21 int find(int k){
22 if (k==f[k])return k;
23 return f[k]=find(f[k]);
24 }
25 void merge(int x,int y){
26 x=find(x),y=find(y);
27 if (x!=y)f[x]=y;
28 }
29 int main(){
30 scanf("%d%d",&n,&m);
31 for(int i=1;i<=n;i++)f[i]=i;
32 for(int i=1;i<=m;i++){
33 scanf("%d%d%d",&a[i],&b[i],&c[i]);
34 in[b[i]]++;
35 out[a[i]]++;
36 merge(a[i],b[i]);
37 ans+=(a[i]!=b[i]);
38 }
39 for(int i=1;i<=n;i++){
40 if ((!in[i])&&(out[i])){
41 printf("-1");
42 return 0;
43 }
44 sz[find(i)]++;
45 if (out[i]>1)vis[find(i)]=1;
46 }
47 bool flag=0;
48 for(int i=1;i<=m;i++)
49 if (a[i]!=b[i]){
50 sum+=c[i]-1;
51 if ((c[i]>1)&&(vis[find(a[i])]))flag=1;
52 }
53 else{
54 if (!vis[find(a[i])])v2.push_back(c[i]-2);
55 else v1.push_back(c[i]-1);
56 }
57 sort(v1.begin(),v1.end(),cmp);
58 sort(v2.begin(),v2.end(),cmp);
59 while ((v1.size())&&(!v1.back()))v1.pop_back();
60 while ((v2.size())&&(v2.back()<=0))v2.pop_back();
61 for(int i=1;i<=n;i++)
62 if ((i==f[i])&&(sz[i]>1)&&(!vis[i]))s++;
63 if (!s){
64 printf("%d",ans);
65 return 0;
66 }
67 ans+=s;
68 if (!flag){
69 if (!v1.size()){
70 printf("-1");
71 return 0;
72 }
73 ans++;
74 s-=v1[0];
75 v1.erase(v1.begin());
76 }
77 s-=sum;
78 for(int i=1;i<v1.size();i++)v1[i]+=v1[i-1];
79 for(int i=1;i<v2.size();i++)v2[i]+=v2[i-1];
80 int mn=min(find1(s),2*find2(s));
81 for(int i=0;i<v1.size();i++)
82 if (v1[i]<s)mn=min(mn,i+1+2*find2(s-v1[i]));
83 if (mn>=oo)printf("-1");
84 else printf("%d",ans+mn);
85 }

[atAGC045E]Fragile Balls的更多相关文章

  1. Codeforces554 C Kyoya and Colored Balls

    C. Kyoya and Colored Balls Time Limit: 2000ms Memory Limit: 262144KB 64-bit integer IO format: %I64d ...

  2. 13 Balls Problem

    今天讨论的是称球问题. No.3 13 balls problem You are given 13 balls. The odd ball may be either heavier or ligh ...

  3. Open judge C16H:Magical Balls 快速幂+逆元

    C16H:Magical Balls 总时间限制:  1000ms 内存限制:  262144kB 描述 Wenwen has a magical ball. When put on an infin ...

  4. hduoj 4710 Balls Rearrangement 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4710 Balls Rearrangement Time Limit: 6000/3000 MS (Java/Ot ...

  5. hdu 3635 Dragon Balls(并查集)

    Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  6. POJ 3687 Labeling Balls()

    Labeling Balls Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9641 Accepted: 2636 Descri ...

  7. Labeling Balls 分类: POJ 2015-07-28 19:47 10人阅读 评论(0) 收藏

    Labeling Balls Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11893 Accepted: 3408 Descr ...

  8. HDU 5810 Balls and Boxes(盒子与球)

     Balls and Boxes(盒子与球) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/O ...

  9. Codeforces Round #158 (Div. 2) C. Balls and Boxes 模拟

    C. Balls and Boxes time limit per test 1 second memory limit per test 256 megabytes input standard i ...

随机推荐

  1. 串的模式匹配 BF算法和KMP算法

    设有主串s和子串t,子串t的定位就是要在主串中找到一个与子串t相等的子串.通常把主串s称为目标串,把子串t称为模式串,因此定位也称为模式匹配. 模式匹配成功是指在目标串s中找到一个模式串t: 不成功则 ...

  2. ❤️【Python从入门到精通】(二十七)更进一步的了解Pillow吧!

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 进一步介绍Pillow库的使用,详细了解 干货满满,建议收藏,需要用到时常看看. 小伙伴们如有问题及需要,欢迎踊跃留言哦~ ~ ~. 前言 本文是 ...

  3. ❤️这应该是Postman最详细的中文使用教程了❤️(新手使用,简单明了)

    ️这应该是Postman最详细的中文使用教程了️(新手使用,简单明了) 在前后端分离开发时,后端工作人员完成系统接口开发后,需要与前端人员对接,测试调试接口,验证接口的正确性可用性.而这要求前端开发进 ...

  4. 初学Python-day12 装饰器函数

    装饰器 1.概念 本质就是一个Python函数,其他函数在本身不变的情况下去增加额外的功能,装饰器的返回值是一个函数. 常用的场景:插入日志,事务处理,缓存,权限校验等. 2.普通函数回顾 1 def ...

  5. 《Spring源码深度解析》学习笔记——Spring的整体架构与容器的基本实现

    pring框架是一个分层架构,它包含一系列的功能要素,并被分为大约20个模块,如下图所示 这些模块被总结为以下几个部分: Core Container Core Container(核心容器)包含有C ...

  6. Beta发布声明

    项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 Beta-发布声明 我们是谁 删库跑路对不队 我们在做什么 题士 进度如何 进度总览 一.功能与特性 1.一 ...

  7. netty系列之:netty实现http2中的流控制

    目录 简介 http2中的流控制 netty对http2流控制的封装 Http2FlowController Http2LocalFlowController Http2RemoteFlowContr ...

  8. 页表 Page tables

    逻辑地址与物理地址的转化 页表是由页表项(PTE)组成的数组.512个PTE构成一个页表页(Page-table page). PTE中包含了物理页码(PPN physical page number ...

  9. opencv学习(一)——图像入门

    图像入门 一.读取图像 在opencv中使用cv.imread(filename, flags)函数读取图像.filename参数表示读取图像的路径.读取图像的路径应完整给出,且不能含有中文,否则在调 ...

  10. Linux 内核网桥源码分析

    Linux网桥源码的实现 转自: Linux二层网络协议 Linux网桥源码的实现 1.调用 在src/net/core/dev.c的软中断函数static void net_rx_action(st ...