正题

题目链接:https://www.luogu.com.cn/problem/P7293


题目大意

有kkk张联通无向图,有kkk个人从每张图的点111出发,定义所有人的位置合为一个状态,求初始状态到达所有能到达状态的最短时间的和。

输出答案对 109+710^9+7109+7 取模。

∑n≤105,∑m≤2×105\sum n\leq 10^5,\sum m\leq 2\times 10^5∑n≤105,∑m≤2×105


解题思路

因为可以反复横跳,对于每个点我们求出到达的最短的奇数/偶数距离,记为dis1/dis2dis1/dis2dis1/dis2。

那么对于一个状态(i1,i2,...,in)(i_1,i_2,...,i_n)(i1​,i2​,...,in​)答案就是
min⁡{max⁡{dis1ij},max⁡{dis2i,j}}\min\{\ \max\{dis1_{i_j}\},\max\{dis2_{i,j}\}\ \}min{ max{dis1ij​​},max{dis2i,j​} }

然后这个又有min⁡\minmin又有max⁡\maxmax的很难搞,但是我们有一个式子a+b=max⁡{a,b}+min⁡{a,b}a+b=\max\{a,b\}+\min\{a,b\}a+b=max{a,b}+min{a,b}(好像很废话),然后就有min⁡{a,b}=a+b−max⁡{a,b}\min\{a,b\}=a+b-\max\{a,b\}min{a,b}=a+b−max{a,b},这样就把max⁡\maxmax消掉了。

那么答案有
max⁡{dis1ij}+max⁡{dis2ij}−max⁡{dis1ij,dis2ij}\max\{dis1_{i_j}\}+\max\{dis2_{i_j}\}-\max\{dis1_{i_j},dis2_{i_j}\}max{dis1ij​​}+max{dis2ij​​}−max{dis1ij​​,dis2ij​​}

然后跑出dis1,dis2dis1,dis2dis1,dis2排个序就很好统计了。

注意不能统计上无法达到的状态。

时间复杂度:O(Nlog⁡N+M)O(N\log N+M)O(NlogN+M)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define mp(x,y) make_pair(x,y)
#define ll long long
using namespace std;
const ll N=2e5+10,P=1e9+7;
struct node{ll to,next;
}a[N<<2];
ll k,n,m,ans,tot,ls[N],c[N],dis[N];
vector<pair<ll,ll> >b[3];
queue<ll> q;
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
}
void addl(ll x,ll y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
void bfs(){q.push(1);dis[1]=1;while(!q.empty()){ll x=q.front();q.pop();for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(dis[y]<=dis[x]+1)continue;dis[y]=dis[x]+1;q.push(y);}}return;
}
void calc(ll id,ll op){ll res=0,now=0;memset(c,0,sizeof(c));for(ll i=0;i<b[id].size();i++){ll d=b[id][i].first,p=b[id][i].second;if(d+1>=dis[0])break;now+=!c[p];c[p]++;ll invn=power(c[p],P-2);if(now==k){res=1;for(int i=1;i<=k;i++)res=res*c[i]%P;}res=res*invn%P;(ans+=res*d*op%P)%=P;res=res*c[p]%P;}return;
}
signed main()
{scanf("%lld",&k);for(ll i=0;i<N;i++)dis[i]=2147483647;for(ll p=1;p<=k;p++){scanf("%lld%lld",&n,&m);for(ll i=1,x,y;i<=m;i++){scanf("%lld%lld",&x,&y);addl(x,y+n);addl(x+n,y);addl(y,x+n);addl(y+n,x);}bfs();for(ll i=1;i<=n;i++){b[0].push_back(mp(dis[i]-1,p));b[1].push_back(mp(dis[i+n]-1,p));b[2].push_back(mp(max(dis[i],dis[i+n])-1,p));}for(ll i=1;i<=2*n;i++)ls[i]=0,dis[i]=dis[0];tot=0;}sort(b[0].begin(),b[0].end());sort(b[1].begin(),b[1].end());sort(b[2].begin(),b[2].end());calc(0,1);calc(1,1);calc(2,-1);printf("%lld\n",(ans+P)%P);return 0;
}

P7293-[USACO21JAN]Sum of Distances P【统计,bfs】相关推荐

  1. MySQL巧用sum,case...when...优化统计查询

    最近在公司做项目,涉及到开发统计报表相关的任务,由于数据量相对较多,之前写的查询语句查询五十万条数据大概需要十秒左右的样子,后来经过老大的指点利用sum,case...when...重写SQL性能一下 ...

  2. LambdaQueryWrapper使用 group分组、sum聚合函数 进行统计,并分页排序

    首先,我们要知道,其实LambdaQueryWrapper是无法使用sum聚合函数的,因为LambdaQueryWrapper的select()方法无法传入字符串,但你有张良计,我有过墙梯,我们其实可 ...

  3. 834. Sum of Distances in Tree

    给定一个无向.连通的树.树中有 N 个标记为 0...N-1 的节点以及 N-1 条边 . 第 i 条边连接节点 edges[i][0] 和 edges[i][1] . 返回一个表示节点 i 与其他所 ...

  4. leetcode 834. Sum of Distances in Tree | 834. 树中距离之和(树形DP)

    题目 https://leetcode.com/problems/sum-of-distances-in-tree/ 题解 一般的算法题,指令条数为 10^8 以内是可以通过的.也就是说,如果 arr ...

  5. 怎么用mysql来统计消费金额限制_mysql——用户消费行为分析

    分析导览:分析目的 1-统计不同性别的消费频次.消费金额 2-统计不同年龄段用户的消费金额 3-统计不同月份的消费金额 4-统计多次消费的用户,第一次和最后一次消费时间的间隔 5-统计不同年龄段的用户 ...

  6. Access数据库中Sum函数返回空值(Null)时如何设置为0

    在完成一个Access表中数据统计时,需要统计指定字段的和,使用到了Sum函数,但统计时发现,指定条件查询统计时有可能返回空值(Null),导致对应字段显示为空白,正常应显示为0.基本思路是在获取记录 ...

  7. 白话Elasticsearch35-深入聚合数据分析之案例实战更多metrics用法:统计每种颜色电视最大最小价格

    文章目录 概述 官方指导 Metrics Aggregations Min Aggregation Max Aggregation Sum Aggregation 案例:统计每种颜色电视最大最小价格 ...

  8. 用php+ajax+echarts.js 实现统计每分钟答题曲线图

    接着上一篇博客,除了实现统计总量外,我还用百度的echart实现了 统计答题曲线图.效果如下:http://newer.gailvlunpt.com/EntranceEducation/admin.p ...

  9. mysql一秒查询次数_单个select语句实现MySQL查询统计次数

    单个select语句实现MySQL查询统计次数 单个select语句实现MySQL查询统计次数的方法用处在哪里呢?用处太多了,比如一个成绩单,你要查询及格得人数与不及格的人数,怎么一次查询出来? My ...

最新文章

  1. 【Azure Services Platform Step by Step-第11篇】Windows Azure兰州拉面馆-日志与队列的使用...
  2. 一不小心肝出了4W字的Redis面试教程
  3. java并发 并行 串行
  4. webpack和vue的按需加载组件、console、抓包
  5. Strom程序的并发机制,配置并行度(代码实现)、动态改变并行度,local or shuffle分组,分组的概念以及分组类型
  6. B. Product(2019ICPC西安邀请赛)(杜教筛)
  7. 在域环境下搭建samba服务器
  8. 前端学习(2422):回顾
  9. Windows Server 2008操作系统安装手册
  10. 镜像上传到linux失败,Docker push镜像失败解决方法
  11. 使用virt-install 创建Xen虚拟机
  12. Linux中的sed命令,使用方法之一「替换字符串中的内容 」,以及「s/ / / 」和「s/ / /g」之间的区别
  13. 在COMSOL中固体力学模块中添加 力矩 扭矩
  14. openjudge 4978 宠物小精灵之收服
  15. 【学术】写文章的框架
  16. OpenCV拷贝与ROI
  17. c语言程序设计 猜数字,猜数字游戏c语言编程,c语言编程 编一个猜数字游戏
  18. win7开启ftp被动模式_Win7上防火墙开放FTP服务以及ping解决方案
  19. 世界首款抗量子攻击商用密码芯片 | 沐创
  20. CSDN 写博客 word文档复制粘贴 图片粘贴 加载失败问题解决

热门文章

  1. linux awk命令总结
  2. html、css、js注释,js,html,css注释大集合
  3. mysql savepoint作用_savepoint原理
  4. dreamweaver连接mysql数据库 发生一个不知名错误_用DREAMWEAVER连接数据库测试时总是弹出发生一个不知名的错误 你好! 请问一下这个问题你是怎么解的?...
  5. layui上传报错会有哪些原因_一到冬天,为什么会比别人更怕冷?有哪些原因?...
  6. java获取机器号_(转)JAVA获得机器码的实现
  7. bcm943602cs蓝牙用不了_原来手机的蓝牙功能这么强大!除了连接耳机,还有这六大实用功能...
  8. java实用教程——组件及事件处理——处理事件
  9. mysql报4934_mysql-Mariadb语法错误1064(42000)
  10. leetcode718. 最长重复子数组