当前位置: 首页 > news >正文

10.03模拟赛t3

CF475E Strongly Connected City 2

题目描述

想象有一座城市,这座城市有 \(n\) 个路口和 \(m\) 条街道。路口编号从 \(1\)\(n\)

为了提高交通流量,市长决定将每条街道改为单行道。这意味着在连接路口 \(u\)\(v\) 的街道上,交通只能从 \(u\)\(v\),或只能从 \(v\)\(u\) 单向通行。

现在的问题是,需要为这些街道指定单向通行的方向,使得能够到达的点对 \((u, v)\) 的数量最大,其中 \(1 \le u, v \le n\),且要求从 \(u\) 出发经过指定方向的街道能够到达 \(v\)。你的任务是找出最大可能的此类点对数量。

题解:

先大概猜猜,发现一个简单的性质,对于一个环,一定满足全部都一个方向最优秀。

所以我们先做一个 tarjan。点权为环的点数。然后发现贪心不大行,考虑 dp

这个时候还要一个性质,对于最优解。就是在只在重心上,能满足其一部分子树的所有点能到达他,其他点都可以从他到达。

证明:

考虑有一个小联通快所有边的方向与其他不同,那么发现把这个所有边全部翻转过来,答案一定变大,因为重心一侧的点至少为所有点的一半。

这下就可以 dp 了。我们把重心作为根,考虑每个点的贡献是多少:

  • (除 \(root\))自己 \(\times\) 自己的子树和

  • 通过重心的到达另一端

其实就是要判断那些子树进入,那些子树要出去。

我们发现第一个贡献不论怎么分配都是一样的。

第二个贡献实际上是一个数学问题:设你进入的节点总数为 \(x\),重心点权为 \(y\) 另一侧点的数量和为 \(z\)。那么有答案为 \((x+y)\times (y+z)\)

那其实就是要找到每一个 \(x\) 能不能被表示出来,这是一个典型的 01背包 直接做复杂度 \(O(n^2)\)bitset 维护的话是 \(\frac{n^2}{w}\) 的。

code:

#include<bits/stdc++.h>
#define pb push_back
#define int long long
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int N=2e5+10;
int n,m,k,T,a[N],vis[N],dfn[N];
int low[N],tot,col,scc[N],siz[N];
int rt,mx=INT_MAX,sz[N],ans,sum;
vector<int> g[N],g1[N];
stack<int> st;
void tar(int u,int fa){dfn[u]=low[u]=++tot;vis[u]=1;st.push(u);for(int v:g[u]){if(v==fa) continue;if(!dfn[v]){tar(v,u);low[u]=min(low[u],low[v]);}else if(vis[v]) low[u]=min(low[u],dfn[v]);}if(low[u]==dfn[u]){col++;while(1){int t=st.top();st.pop();scc[t]=col;vis[t]=0;siz[col]++;if(t==u) break;}}
}
void getrt(int u,int fa){sz[u]=siz[u];int res=0;for(int v:g1[u]){if(v==fa) continue;getrt(v,u);sz[u]+=sz[v];res=max(res,sz[v]);}res=max(res,n-sz[u]);if(res<mx) mx=res,rt=u;
}
void dfs(int u,int fa){sz[u]=siz[u];for(int v:g1[u]){if(v==fa) continue;dfs(v,u);sz[u]+=sz[v];}if(fa)sum+=siz[u]*sz[u];
}
bitset<N> s; 
signed main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>n>>m;rep(i,1,m){int u,v;cin>>u>>v;g[u].pb(v);g[v].pb(u);}tar(1,0);rep(i,1,n){for(int v:g[i]){if(scc[i]!=scc[v]){g1[scc[i]].pb(scc[v]);}}}rt=0;getrt(1,0);dfs(rt,0);s[0]=1;if(g1[rt].size()==n-1){cout<<1ll*((n-1)/2)*(n-((n-1)/2))+(n-((n-1)/2)-1)+n;return 0;	}for(int v:g1[rt]){s=s|(s<<sz[v]);}rep(i,0,n){if(s[i]==1){ans=max(ans,(i+siz[rt])*(n-i));}}cout<<ans+sum;return 0;
}
http://www.gsyq.cn/news/15253.html

相关文章:

  • 打工人日报#20250927 - 教程
  • GPT-5 撼动量子计算:AI 在科研领域的颠覆性应用 - 实践
  • python 肘部法则,判点聚类分为几类,K-means聚类分析
  • 《系统与软件工程功能规模测量IFPUG手段》(GB/T42449-2023)标准解读
  • lesson70:jQuery Ajax完全指南:从基础到4.0新特性及现代替代优秀的方案引言:jQuery Ajax的时代价值与演进
  • 详细介绍:计算机视觉:OpenCV+Dlib 人脸检测
  • 详细介绍:Jenkins:持续集成和持续交付(CI/CD)工具
  • 和水导学习的第二篇笔记
  • 百度电商MultiAgent视频生成系统 - 详解
  • 为博客写遗言
  • 新能源汽车整车电控环境详解!
  • 《吃透 C++ vector:从基础使用到核心接口实战指南》 - 指南
  • 黑马程序员苍穹外卖学习指南(本文消除我跟视频做该项目时遇到的问题和解决方法)
  • 网络流 费用流 EK算法
  • Python 新手入门:从零开始学习 Python 的 10 个关键步骤
  • EPL S22 Stage 2 赛前前瞻
  • 实用指南:Guava Cache
  • 计算机类毕业设计开题报告注意事项 - 教程
  • 微信社群机器人搭建 教程/开发
  • 微信智能机器人开发-基于WTAPI框架,实现强大的个微管理
  • Kafka 安全SASL 认证全栈实战从 JAAS 到 Kerberos、PLAIN、SCRAM、OAUTH 与委托令牌 - 教程
  • glibc堆
  • 小作业 11
  • US$948 WOYO UC009 Ultrasonic Cutter for Cutting Plastic
  • 深入解析:【RabbitMQ】原理解析
  • 2025年电子设备行业最受欢迎的5款CRM推荐
  • AT_abc266_g [ABC266G] Yet Another RGB Sequence
  • 深入解析:Visual RM 用智能引擎重塑企业协作新模式!
  • Win7下bat条件满足语句不执行的奇怪案例
  • 3.8 材料链路层设备 (答案见原书 P122)