构造一张有向图$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. 基于go语言学习工厂模式

    工厂模式 简单工厂模式(Simple Factory) 定义 优点 缺点 适用范围 代码实现 工厂方法模式(Factory Method) 定义 优点 缺点 适用范围 代码实现 抽象工厂模式(Abst ...

  2. Spring IOC Container原理解析

    Spring Framework 之 IOC IOC.DI基础概念 关于IOC和DI大家都不陌生,我们直接上martin fowler的原文,里面已经有DI的例子和spring的使用示例 <In ...

  3. 题解 CF468C Hack it!

    题目传送门 Description 设 \(f(i)\) 表示 \(i\) 的数码只和,给出 \(a\),求出 \(l,r\) 使得 \(\sum_{i=l}^{r} f(i)\equiv 0\pmo ...

  4. 多项式(polynomial)

    多项式(polynomial) 题目大意: 给出一个 n 次多项式 \(f(x)=\sum_{i=0}^na_ix^i\) 对于\(k ≤ x ≤ k + l − 1\) 的\(l\) 个\(x\), ...

  5. vue3.x全局插件和组件

    做vue项目的时候,总有一些小组件或者工具类,我们需要频繁的使用,每个使用的地方再去引用相对比较麻烦,当然也有一些好处,尤其是配合组件异步加载的时候,能最更好的减少项目首次加载的体积,从而优化一些体验 ...

  6. 微信小程序的支付流程

    一.前言 微信小程序为电商类小程序,提供了非常完善.优秀.安全的支付功能 在小程序内可调用微信的API完成支付功能,方便.快捷 场景如下图所示: 用户通过分享或扫描二维码进入商户小程序,用户选择购买, ...

  7. 看动画学算法之:队列queue

    目录 简介 队列的实现 队列的数组实现 队列的动态数组实现 队列的链表实现 队列的时间复杂度 简介 队列Queue是一个非常常见的数据结构,所谓队列就是先进先出的序列结构. 想象一下我们日常的排队买票 ...

  8. [敏捷软工团队博客]项目介绍 & 需求分析 & 发布预测

    项目 内容 2020春季计算机学院软件工程(罗杰 任健) 博客园班级博客 作业要求 团队项目选择 我们在这个课程的目标是 在团队合作中锻炼自己 这个作业在哪个具体方面帮助我们实现目标 了解项目整体情况 ...

  9. Spring Security Jwt Token 自动刷新

    token的自动刷新 一.功能需求 二.功能分析 1.token 的生成 2.token 的自动延长 3.系统资源的保护 4.用户如何传递 token 三.实现思路 1.生成 token 和 refr ...

  10. 主集天线和分集天线——4G天线技术

    主集天线和分集天线 分集接收技术是一项主要的抗衰落技术,可以大大提高多径衰落信道传输下的可靠性,在实际的移动通信系统中,移动台常常工作在城市建筑群或其他复杂的地理环境中,而且移动的速度和方向是任意的. ...