Boboniu Walks on Graph【CF-1395E】【哈希】

题目链接


  有N个点的,M条有向边组成的图,每个点的出度都小于等于K,现在要求我们求这样的K元组(c_1, c_2, \cdots , c_k)意思是出度为i的点,选择边权第c_i小的边走,最后要求满足所有的点一定是能走回该点。

  那么,题意其实也就是每个点最后只有一条出边,并且因为要求形成环,所以每个点最多被进一次(不然就一定是无解的)。

  所以,这道题就是O(K!)去枚举,然后如何记录状态呢?最开始的时候我想了个bitset的解法,但是发现其实这样会很多元素会被多次处理,所以这样的做法就浪费了,所以我们不如直接使用哈希,复杂度O(1)来进行操作。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define pii pair
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 2e5 + 7;
const ull h1 = 1e9 + 7;
int N, M, K, du[maxN] = {0};
vector E[maxN];
int ans = 0;
vector have_du[10];
ull x, save[10][10], need, Bas[maxN];
void dfs(int deep, int tim)
{
    if(!deep)
    {
        if(x == need) ans += tim;
    }
    else
    {
        if(have_du[deep].empty()) dfs(deep - 1, tim * deep);
        else for(int i=1; i<=deep; i++)
        {
            x += save[deep][i];
            dfs(deep - 1, tim);
            x -= save[deep][i];
        }
    }
}
int main()
{
    Bas[0] = 1;
    for(int i=1; i

 

你可能感兴趣的:(思维,哈希,哈希)