[BZOJ5109/CodePlus2017]大吉大利,晚上吃鸡!
Description
最近《绝地求生:大逃杀》风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏。在游戏中,皮皮和毛毛最喜欢做的事情就是堵桥,每每有一个好时机都能收到不少的快递。当然,有些时候并不能堵桥,皮皮和毛毛会选择在其他的必经之路上蹲点。K博士作为一个老年人,外加有心脏病,自然是不能玩这款游戏的,但是这并不能妨碍他对这款游戏进行一些理论分析,比如最近他就对皮皮和毛毛的战士很感兴趣。【题目描述】游戏的地图可以抽象为一张n个点m条无向边的图,节点编号为1到n,每条边具有一个正整数的长度。假定大魔王都会从S点出发到达T点(S和T已知),并且只会走最短路,皮皮和毛毛会在A点和B点埋伏大魔王。
为了保证一定能埋伏到大魔王,同时又想留大魔王一条生路,皮皮和毛毛约定A点和B点必须满足:
1.大魔王所有可能路径中,必定会经过A点和B点中的任意一点
2.大魔王所有可能路径中,不存在一条路径同时经过A点和B点
K博士想知道,满足上面两个条件的A,B点对有多少个,交换A,B的顺序算相同的方案
Input
第一行输入四个整数n,m,S,T(1≤n≤5×104,1≤m≤5×104,1≤S,T≤n),含义见题目描述。
接下来输入m行,每行输入三个整数u,v,w(1≤u,v≤n,1≤w≤10^9)表示存在一条长度为w的边链接u和v。
1≤n≤5×104,1≤m≤5×104,1≤w≤10^9
Output
输出一行表示答案
Sample Input
7 7 1 7
1 2 2
2 4 2
4 6 2
6 7 2
1 3 2
3 5 4
5 7 2
Sample Output
6
首先预祝你们落地成盒(逃
话说大家喜欢用些什么枪啊,步枪还是狙击枪(ヽ( ̄︿ ̄ )—C<(/°Д°)/,又不好好讲题了,拖走
咳,我们还是回到正题,首先我们简化一下题面:若存在点对\((x,y)\),满足所有S到T的最短路,存在任意一条经过且只经过一个点,且所有最短路不会同时经过两个点,那么这个点对就是合法的,求合法点对的个数
首先我们求出所有S到T的最短路,将其作为一张新图,并统计新图内的点数,首先利用乘法原理,一个点在最短路上,一个点不在,求出一部分答案。
然后考虑新图内的答案,我们在选定一个点之后,该点向T方向走能到达的所有点都是不可选的,同理,所有从S方向能走到它的点也是不可选的。如何记录这些点?Hash或bitset。然后由于会算重,我们除2即可
注意,如果S->T不连通,我们需要输出\(\binom{n}{2}\)
/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 1e18
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x>=10) print(x/10);
putchar(x%10+'0');
}
const int N=5e4;
int pre[(N<<1)+10],now[N+10],child[(N<<1)+10],val[(N<<1)+10];
int tot;
ll Ans,Low_Dis;
struct S1{
ll dis[N+10];
S1(){memset(dis,63,sizeof(dis));}
}Frw,Bck;
int h[N+10],f[N+10];
bool vis[N+10],In[N+10];
void join(int x,int y,int z){pre[++tot]=now[x],now[x]=tot,child[tot]=y,val[tot]=z;}
void insert(int x,int y,int z){join(x,y,z),join(y,x,z);}
void SPFA(int x,ll *dis){
int head=0,tail=1;
h[1]=x,dis[x]=0,vis[x]=1;
while (head!=tail){
if (++head>N) head=1;
int Now=h[head];
for (int p=now[Now],son=child[p];p;p=pre[p],son=child[p]){
if (dis[son]>dis[Now]+val[p]){
dis[son]=dis[Now]+val[p];
if (!vis[son]){
if (++tail>N) tail=1;
vis[h[tail]=son]=1;
}
}
}
vis[Now]=0;
}
}
bitset<N>bit[N+10],tmp(1);
void dfs_S(int x,int fa,int T){
bit[x]|=tmp<<(x-1);
if (x==T) return;
for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){
if (son==fa||Frw.dis[x]+val[p]+Bck.dis[son]!=Low_Dis) continue;
dfs_S(son,x,T);
bit[x]|=bit[son];
}
}
void dfs_T(int x,int fa,int T){
bit[x]|=tmp<<(x-1);
if (x==T) return;
for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){
if (son==fa||Bck.dis[x]+val[p]+Frw.dis[son]!=Low_Dis) continue;
dfs_T(son,x,T);
bit[x]|=bit[son];
}
}
int main(){
int n=read(),m=read(),S=read(),T=read(),All=0;
for (int i=1;i<=m;i++){
int x=read(),y=read(),z=read();
insert(x,y,z);
}
SPFA(S,Frw.dis);
SPFA(T,Bck.dis);
Low_Dis=Frw.dis[T];
for (int i=1;i<=n;i++) if (Frw.dis[i]+Bck.dis[i]==Low_Dis) In[i]=1,All++;
if (Low_Dis>inf){
printf("%lld\n",1ll*n*(n-1)/2);
return 0;
}
dfs_S(S,0,T);
for (int i=1;i<=n;i++) if (In[i]) f[i]+=bit[i].count(),bit[i].reset();
dfs_T(T,0,S);
for (int i=1;i<=n;i++) if (In[i]) f[i]+=bit[i].count()-1;
Ans=1ll*All*(n-All);
ll res=0;
for (int i=1;i<=n;i++) if (In[i]) res+=All-f[i];
printf("%lld\n",Ans+(res>>1));
return 0;
}
[BZOJ5109/CodePlus2017]大吉大利,晚上吃鸡!的更多相关文章
- [BZOJ5109]大吉大利,晚上吃鸡!
[BZOJ5109]大吉大利,晚上吃鸡! 题目大意: 一张\(n(n\le5\times10^4)\)个点\(m(m\le5\times10^4)\)条边的无向图,节点编号为\(1\)到\(n\),边 ...
- 【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡! 最短路+拓扑排序+DP
[BZOJ5109][CodePlus 2017]大吉大利,晚上吃鸡! Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏 ...
- GMA Round 1 大吉大利,晚上吃鸡
传送门 大吉大利,晚上吃鸡 新年走亲访友能干点啥呢,咱开黑吃鸡吧. 这里有32个人,每个人都可能想玩或者不想玩,这样子一共有$2^{32}$种可能.而要开黑当然得4人4人组一队(四人模式),所以说如果 ...
- 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 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏中,皮皮 和毛毛最喜欢做的事情就是堵桥,每每有一个好时机都能收到不少的快 ...
- 「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的路径,$ ...
- [Code+#1]大吉大利,晚上吃鸡!
输入输出样例 输入样例#1: 7 7 1 7 1 2 2 2 4 2 4 6 2 6 7 2 1 3 2 3 5 4 5 7 2 输出样例#1: 6 输入样例#2: 5 5 1 4 1 2 1 1 3 ...
- luogu4061 大吉大利,晚上吃鸡!
链接 最短路径\(dag\),一道好题. 题目大意:求一张图中满足下列要求的点对\((i,j)\)数量: 所有最短路径必定会经过 \(i\) 点和 \(j\) 点中的任意一点. 不存在一条最短路同时经 ...
随机推荐
- 【01染色法判断二分匹配+匈牙利算法求最大匹配】HDU The Accomodation of Students
http://acm.hdu.edu.cn/showproblem.php?pid=2444 [DFS染色] #include<iostream> #include<cstdio&g ...
- [NOIP2007] 提高组 洛谷P1097 统计数字
题目描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出 ...
- Redis 配置【十】
参考:http://www.runoob.com/redis/redis-conf.html Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf. 你可以通过 CONF ...
- 洛谷 P4379 [USACO18OPEN]Lemonade Line
P4379 [USACO18OPEN]Lemonade Line 题目描述 这是农场上一个炎热的夏日,Farmer John要给他的 NN 头奶牛发柠檬汽水了!所有的 NN 头奶牛(方便起见,编号为 ...
- Ubuntu 16.04 GNOME下解决Sublime Text3中文输入(ibus)(转)
解决方法: 1.进入Sublime Text3插件管理文件夹 cd ~/.config/sublime-text-3/Packages 2.获取InputHelper插件 git clone http ...
- 模拟用户点击弹出新页面不会被浏览器拦截_javascript技巧
原文:http://www.html5cn.com.cn/article/zxzx/3195.html 相信用过window.open的小伙伴们都遇到过被浏览器拦截导致页面无法弹出的情况:我们换下思路 ...
- ArcEngine 打开AutoCAD文件的几种方法
方法一. IWorkspaceFactory pWorkspaceFactory; IFeatureWorkspace pFeatureWorkspace; IFeatureLayer pFeatur ...
- android 深入浅出 群内“每日一问” 问答总结
永远不变的就是变. 俗话说的好,环境改变人生. 常常面对的是一群积极奋进的人,那么你的心态和生活也会变的充满斗志.青春在于折腾,趁我们还年轻,拿出你的激情.踏着泪水载着梦,才干拥有自己的一片天空. 上 ...
- Canny算法源码,欢迎交流
http://blog.csdn.net/jianxiong8814/article/details/1563109 http://blog.csdn.net/assuper/article/deta ...
- ps图片怎样实现渐变
首先我先将一副图片展示给大家: 我所做的效果是想把图片做成渐变.而不改变中间图片的颜色效果. 接下来我来说明一下我的所做思路. 首先将图片中间部分选择出来.然后复制成一个图层. 详细操作是用魔棒进行反 ...