【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡! 最短路+拓扑排序+DP
【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡!
Description
Input
Output
Sample Input
1 2 2
2 4 2
4 6 2
6 7 2
1 3 2
3 5 4
5 7 2
Sample Output
【样例 1 解释】
合法的方案为 < 2, 3 >, < 2, 4 >, < 4, 3 >, < 4, 5 >, < 6, 3 >, < 6, 5 > 。
题解:第一思路是先随便找出一条最短路,那么最终的A点和B点一定有一个在这条最短路上,我们设在路径上的是A。于是我们枚举所有点B,考虑它可以搭配哪些合法的点A。 不难发现,为了满足条件2,可以选择的点A一定在一段区间中(如果能从B走到A,那么B也一定能走到A后面的点;如果A能走到B,那么A前面的点也一定能走到B),我们可以先求出最短路径图,然后在正图和反图上分别跑拓扑排序+DP,就能得出每个B的合法A区间。
那么条件1如何满足呢?我们可以用拓扑排序求出经过点i的最短路径条数f[i],那么如果A和B满足条件1,等价于f[A]+f[B]=f[T],所以我们可以采用差分的方式,将每个B的f值扔到对应的A区间中,然后枚举所有A,用map维护当前有多少个点的f值等于一个数,每枚举到一个A就查询一下有多少个点的f等于f[T]-f[A]即可。不过f值可能很大,我们可以采用取模的方式,如果感觉还是很虚的话,可以多取几个模数(本人取了两个)。
但是,考试时写了一发只有55分,为什么?45分的数据S和T都不连通,此时要输出$C_n^2$!输出$C_n^2$能得45分也就算了,我后来check了一下数据,发现所有图都是随机的,所有数据中从S到T的最短路最多只有1条!所以呢,本题其实只需要先特判S和T是否连通,若不连通则输出$C_n^2$,否则随便找一条S到T的最短路,设路径上的点数为len,输出len*(n-len)即能得到满分。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <utility>
#include <map>
#include <vector>
#define mp(A,B) make_pair(A,B)
using namespace std;
typedef long long ll;
const int maxn=50010;
const ll P1=998244353;
const ll P2=1000000007;
int n,m,cnt,len,S,T;
ll ans;
struct node
{
ll x,y;
node() {}
node(ll a,ll b) {x=a,y=b;}
node operator + (const node &a) const {return node((x+a.x)%P1,(y+a.y)%P2);}
node operator * (const node &a) const {return node(x*a.x%P1,y*a.y%P2);}
node operator - (const node &a) const {return node((x-a.x+P1)%P1,(y-a.y+P2)%P2);}
bool operator < (const node &a) const {return (x==a.x)?(y<a.y):(x<a.x);}
}f1[maxn],f2[maxn],f[maxn];
priority_queue<pair<ll,int> > pq;
queue<int> q;
int to[maxn<<1],next[maxn<<1],head[maxn],vis[maxn],d[maxn],pre[maxn],lm[maxn],rm[maxn],p[maxn];
//l正r反
ll val[maxn<<1],s1[maxn],s2[maxn];
map<node,int> s;
vector<node>::iterator it;
vector<node> p1[maxn],p2[maxn];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
inline void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
int main()
{
//freopen("7.in","r",stdin);
n=rd(),m=rd(),S=rd(),T=rd();
int i,j,a,b,c,u,v;
memset(head,-1,sizeof(head)),memset(s1,0x3f,sizeof(s1)),memset(s2,0x3f,sizeof(s2));
for(i=1;i<=m;i++) a=rd(),b=rd(),c=rd(),add(a,b,c),add(b,a,c);
s1[S]=0,pq.push(mp(0,S));
while(!pq.empty())
{
u=pq.top().second,pq.pop();
if(vis[u]) continue;
vis[u]=1;
for(i=head[u];i!=-1;i=next[i]) if(s1[to[i]]>s1[u]+val[i])
s1[to[i]]=s1[u]+val[i],pq.push(mp(-s1[to[i]],to[i]));
}
if(s1[T]==0x3f3f3f3f3f3f3f3fll)
{
printf("%lld",(ll)n*(n-1)/2);
return 0;
}
s2[T]=0,pq.push(mp(0,T)),memset(vis,0,sizeof(vis));
while(!pq.empty())
{
u=pq.top().second,pq.pop();
if(vis[u]) continue;
vis[u]=1;
for(i=head[u];i!=-1;i=next[i]) if(s2[to[i]]>s2[u]+val[i])
s2[to[i]]=s2[u]+val[i],pre[to[i]]=u,pq.push(mp(-s2[to[i]],to[i]));
}
for(i=S;i;i=pre[i]) p[++len]=i,lm[i]=len+1,rm[i]=len-1;
for(i=1;i<=n;i++) if(!lm[i]) lm[i]=1,rm[i]=len;
for(i=1;i<=n;i++) for(j=head[i];j!=-1;j=next[j]) if(val[j]>0&&s1[i]+s2[to[j]]+val[j]==s1[T])
val[j]=-1,val[j^1]=-2,d[to[j]]++;
for(i=1;i<=n;i++) if(!d[i]) q.push(i);
f1[S]=node(1,1),f2[T]=node(1,1);
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=next[i]) if(val[i]==-1)
{
v=to[i],d[v]--,f1[v]=f1[v]+f1[u],lm[v]=max(lm[v],lm[u]);
if(!d[v]) q.push(v);
}
}
for(i=1;i<=n;i++) for(j=head[i];j!=-1;j=next[j]) if(val[j]==-2) d[to[j]]++;
for(i=1;i<=n;i++) if(!d[i]) q.push(i);
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=next[i]) if(val[i]==-2)
{
v=to[i],d[v]--,f2[v]=f2[v]+f2[u],rm[v]=min(rm[v],rm[u]);
if(!d[v]) q.push(v);
}
}
for(i=1;i<=n;i++)
{
f[i]=f1[i]*f2[i];
if(lm[i]<=rm[i]) p1[lm[i]].push_back(f[i]),p2[rm[i]].push_back(f[i]);
}
for(i=1;i<=len;i++)
{
for(it=p1[i].begin();it!=p1[i].end();it++) s[*it]++;
ans+=s[f[T]-f[p[i]]];
for(it=p2[i].begin();it!=p2[i].end();it++) s[*it]--;
}
printf("%lld",ans);
return 0;
}
【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡! 最短路+拓扑排序+DP的更多相关文章
- BZOJ5109 CodePlus 2017大吉大利,晚上吃鸡!(最短路+拓扑排序+bitset)
首先跑正反两遍dij求由起点/终点到某点的最短路条数,这样条件一就转化为f(S,A)*f(T,A)+f(S,B)*f(T,B)=f(S,T).同时建出最短路DAG,这样图中任何一条S到T的路径都是最短 ...
- bzoj5109: [CodePlus 2017]大吉大利,晚上吃鸡!
Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏中,皮皮 和毛毛最喜欢做的事情就是堵桥,每每有一个好时机都能收到不少的快 ...
- [BZOJ5109][LOJ #6252][P4061][CodePlus 2017 11月赛]大吉大利,今晚吃鸡!(最短路+拓扑排序+传递闭包+map+bitset(hash+压位))
5109: [CodePlus 2017]大吉大利,晚上吃鸡! Time Limit: 30 Sec Memory Limit: 1024 MBSubmit: 107 Solved: 57[Sub ...
- [BZOJ5109]大吉大利,晚上吃鸡!
[BZOJ5109]大吉大利,晚上吃鸡! 题目大意: 一张\(n(n\le5\times10^4)\)个点\(m(m\le5\times10^4)\)条边的无向图,节点编号为\(1\)到\(n\),边 ...
- GMA Round 1 大吉大利,晚上吃鸡
传送门 大吉大利,晚上吃鸡 新年走亲访友能干点啥呢,咱开黑吃鸡吧. 这里有32个人,每个人都可能想玩或者不想玩,这样子一共有$2^{32}$种可能.而要开黑当然得4人4人组一队(四人模式),所以说如果 ...
- 「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡!(dij+bitset)
从S出发跑dij,从T出发跑dij,顺便最短路计数. 令$F(x)$为$S$到$T$最短路经过$x$的方案数,显然这个是可以用$S$到$x$的方案数乘$T$到$x$的方案数来得到. 然后第一个条件就变 ...
- 「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡!
n<=50000,m<=50000的图,给s和t,问有多少点对$(a,b)$满足 嗯. 不会. 首先最短路DAG造出来,然后两个条件转述一下:条件一,$N_a$表示从s到t经过a的路径,$ ...
- LOJ6252. 「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡! 最短路+bitset
题目传送门 https://loj.ac/problem/6252 https://lydsy.com/JudgeOnline/problem.php?id=5109 题解 首先跑最短路,只保留 \( ...
- [BZOJ5109/CodePlus2017]大吉大利,晚上吃鸡!
Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏中,皮皮和毛毛最喜欢做的事情就是堵桥,每每有一个好时机都能收到不少的快递 ...
随机推荐
- 解决Spring框架的Dao层改用@Repository注解,无法使用JdbcDaoSupport的问题
解决Spring框架的Dao层改用@Repository注解,无法使用JdbcDaoSupport的问题 Alternatively, create an own implementation of ...
- Ajax轮询——“定时的通过Ajax查询服务端”
Ajax轮询——"定时的通过Ajax查询服务端". 概念: 轮询(polling):客户端按规定时间定时像服务端发送ajax请求,服务器接到请求后马上返回响应信息并关闭连接. 百闻 ...
- .net 高级写法总结
1.处理HTTP非正常的请求参数: [1] 获取相应的流转为string [2] request 的只读属性设置为可编辑,类似form [3] 转换为json对象 [4] 重设只读属性 //判断请求类 ...
- 让IE6支持min-height,max-height等的方法
1.IE6支持max-height解决方法 IE6支持最大高度解决CSS代码:.yangshi{max-height:1000px;_height:expression((document.do ...
- 关于Cocos2d-x中节点和精灵的关系以及初始化
1.每一个对象类都有一个自己public的一个create函数(等价于CREATE_FUNC),和init函数. 2.create函数返回的是自身的类型,init函数是在ceate函数被调用的时候自动 ...
- Spring 依赖注入(DI)的注解
Spring中想要使用注解进行依赖注入,需要进行如下配置: <beans xmlns="http://www.springframework.org/schema/beans" ...
- 第二百九十三,Memcached缓存
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached ...
- e581. Animating an Array of Images in an Application
This is the simplest application to animate an array of images. import java.awt.*; import javax.swin ...
- C++ 编译器用于把源代码编译成最终的可执行程序
C++ 编译器写在源文件中的源代码是人类可读的源.它需要"编译",转为机器语言,这样 CPU 可以按给定指令执行程序. C++ 编译器用于把源代码编译成最终的可执行程序. 大多数的 ...
- CentOS6.8忘记root密码的解决办法(开始初始化也可以用)
在开机启动的时候按键盘上的“E”键会进入如下界面. 选择相应的内核,再次按“E”,出现下图,选择第二项,再次按“E”键 经过第二步,这个画面可以编辑,在信息的最后加“空格”,然后键入“single”( ...