---题面--- 题解: 考场上看的这道题,,,当时70分算法打挂了,今天才知道这个也是原题.... 首先,对于不跟1相邻的边,肯定不会经过两次,因为经过两次就回来了,除了增加路径长度之外没有任何意义. 但是跟1相邻的边是可能会经过2次的,因为虽然增加了路径长度,但这次回来就直接到终点了,所以完全可能重复走. 那么有一个很容易发现的思路是,我们可以强制某一条边是出边(即从1点出去可以走的边),其他边则为入边,这样的话就可以强制走不同的路了,但这样时间复杂度较大.考虑优化它. 可以发现,这样分组的…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 按二进制每一位是 0/1 把 1 号点的儿子分成两组,分别作为起点和终点跑多起点最短路,最优解的起点和终点总有一次会被分到不同组里: 太久没写 dijkstra 竟然WA了4次...别忘了 priority_queue 是大根堆-_-,还要注意循环计数的 i,j 不要重了... 代码如下: #include<iostream> #include<cstdio> #inc…
二进制分组也可以说是一种比较优美的拆贡献方式吧? Description 菩萨为行,福慧双修,智人得果,不忘其本.——唐朠立<大慈恩寺三藏法师传>有才而知进退,福慧双修,这才难得.——乌雅氏如何福慧双修?被太后教导的甄嬛徘徊在御花园当中.突然,她发现御花园中的花朵全都是红色和蓝色的.她冥冥之中得到了响应:这就是指导她如何福慧双修的! 现在御花园可以看作是有N块区域,M条小路,两块区域之间可通过小路连接起来.现在甄嬛站在1号区域,而她需要在御花园中绕一绕,且至少经过1个非1号区 域的区域.但是恰…
正边权无向图,一条边两个方向权值不一定相同,求经过点1的最小简单环 简单环包含了点1的一条出边和一条入边,且这两条边不同,因此可以枚举这两条边的编号的二进制表示中哪一位不同,用最短路求此时的最优解,时间复杂度$O(mlog^2m)$ #include<bits/stdc++.h> using std::swap; using std::vector; using std::priority_queue; ,inf=; int _(){ ,c=getchar(); )c=getchar(); )…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 如果枚举1号点走哪些点出去,就从那些点出发跑多源最短路即可.最短路不会重复经过一条边. 怎样枚举较优?需要枚举到答案的起点在一组.终点在另一组:考虑按点的编号二进制分组,即枚举每一位,为0的在一组,为1的在另一组. 因为两个点编号不同,所以二进制表示至少有1位不同,即任意两个点一定一度被分到过两个组里. 好像还有构造新图的更快的做法.不过也没管. #include<iostream>…
题目大意: 给定一个$n(n\leq40000)$个点$m(m\leq100000)$条边的有向图,求从$1$出发回到$1$的不经过重复结点的最短路. 思路: 首先Dijkstra求出从1出发到每个结点$i$的单源最短路$dis[i]$及经过的第一个结点$first[i]$. 考虑重构图,将起点与终点区分开来,新建结点$n+1$表示终点. 枚举原图中的每一条边$(x,y,w)$,表示从$x$到$y$边权为$w$. 若$x=1,first[y]\ne y$,在新图中保留这条边: 若$y=1,fir…
题意: 此题中S=1 思路:Orz ManGod秒切此题 我觉得出入边权互换不太直观,就改了一下写法 第一次默认与1有关的第一条出边只出不入,第二次默认只入不出 ..]of longint; head,vet,next,len,flag,x,y,z,w,id,a,b,c,d:..]of longint; inq:..]of boolean; n,m,bz,t3,t4,tot,h1,t1,i,j,ans,m1,t,tmp:longint; procedure add(a,b,c:longint);…
二进制分组,算个小技巧 bzoj 4398福慧双修 给一张图,同一条边不同方向权值不同,一条边只能走一次,求从1号点出发再回到1号点的最短路 一开始没注意一条边只能走一次这个限制,打了个从一号点相邻节点为原点的dij,样例就挂了 其实就是要从这个错误思路上改进 对于不与1号点相接的边,权值为正,肯定不会重复走,所以这个条件可以忽略 考虑1号点相邻的点,走出第一步后所在的点,和走回1号点前的那个点不能相同 设这两个点编号为\(i\),\(j\),则\(i\),\(j\)的二进制至少有一位不同 所以…
题意:给你n个点m条边的有向图,然后再给你k个不同的点,问你这k个点的最小距离: 解题思路:这道题最需要注意的就是k个点一定是不同的,那么有一个结论就是任意两个不同的数字中,在他们的二进制地表示中,一定有一位是不同的,这样,我们就可以按照这个规律,把这些数字分成两组,按他们的二进制在某一位是0或者1分组,然后对每一位都跑一次最短路,这里的数据的二进制不超过20位 #include<iostream> #include<algorithm> #include<cstdio>…
题意 给出一个\(n\)个点\(m\)条边的有向图\((n,m<=100000)\),从中选择\(k\)个点\((k<=n)\),问这k个点两两之间的最短路最小值是多少? 思路 直接的想法是对于每个点求一遍最短路,这样一共要跑n次最短路,时间复杂度\(O(nmlogm)\). 考虑两个点集\(S1\)和\(S2\)之间的最短路,我们可以跑一次最短路求出来. 具体可以新建虚拟源点\(s\)和虚拟汇点\(t\),\(s\)和\(S1\)的每个点之间连一条零边,\(t\)同理. 那么这一次最短路就相…