CF 11D A Simple Task 题解

题面

这道题的数据范围一看就是dfs或状压啦~

本文以状压的方式来讲解

f[i][j]表示目前的节点是i,已经经历过的节点的状态为j的简单环的个数;

具体的转移方程和细节请看代码;

PS:(i&-i)的意义便是树状数组

#include <bits/stdc++.h>
using namespace std;
int n,m;
int a[20][20];
long long f[20][1000010];
long long ans;
int main ()
{
    cin>>n>>m;
    for(register int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        a[u][v]=1; a[v][u]=1;
    }
    for(int i=1;i<=n;i++)  f[i][1<<(i-1)]=1;
    for(int i=1;i<=1<<(n);i++){ //状态,其中i&-i是起点
        for(int j=1;j<=n;j++){ //n^2枚举点
            for(int k=1;k<=n;k++){
                if(!a[j][k]) continue;
                if((i&-i)>1<<(k-1)) continue; //如果这个点回到了比起点还起点的点,那么就违规了;
                if(1<<(k-1)&i){ //如果这个点已经遍历过
                    if(1<<(k-1)==(i&-i)){   //如果这个点k是状态i的起点(代表又一次回到了起点)
                        ans+=f[j][i];
                    }
                    else{
                        continue;
                    }
                }
                else{
                    f[k][i|(1<<(k-1))]+=f[j][i];
                }
            }
        }
    }
    cout<<(ans-m)/2;
}

原文地址:https://www.cnblogs.com/kamimxr/p/11280397.html

时间: 2024-10-09 04:07:13

CF 11D A Simple Task 题解的相关文章

cf 11D A Simple Task(数压DP)

题意: N个点构成的无向图,M条边描述这个无向图. 问这个无向图中共有多少个环. (1 ≤ n ≤ 19, 0 ≤ m) 思路: 例子: 4 6 1 2 1 3 1 4 2 3 2 4 3 4 答案:7 画个图发现,直接暴力DFS有太多的重复计算.用DP. 枚举点数(状态),每个状态的起点.终点(起点可以不用枚举,因为反正是一个环,谁作为起点都一样). dp[S][i]:状态是S,i是终点   含义:从S中的第一个数s出发到达第i个点的方案数.如果s和i相加,总方案数ans+=dp[S][i]

[CodeForces 11D] A Simple Task - 状态压缩入门

状态压缩/Bitmask 在动态规划问题中,我们会遇到需要记录一个节点是否被占用/是否到达过的情况.而对于一个节点数有多个甚至十几个的问题,开一个巨型的[0/1]数组显然不现实.于是就引入了状态压缩,用一个整数的不同二进制位来表示该节点的状态. Description Given a simple graph, output the number of simple cycles in it. A simple cycle is a cycle with no repeated vertices

Codeforces 11D - A Simple Task (状压DP)

题意 求出一个n个点m个边的图,求简单环有多少(没有重复点和边). 思路 这是个不错的题,这个状压dp保存的状态不是直接的环,而是路径的个数.s表示的状态为一条路径,则dp[s][i]表示以s的最小编号为起点,以i为终点的环的个数.那么我们就可以通过枚举状态,枚举状态中的起点和枚举路径外的终点,然后判断终点和起点是否相连来判断是否成环. 代码 #include <stdio.h> #include <string.h> #include <iostream> #incl

CodeForces 11D A Simple Task

题目:http://codeforces.com/problemset/problem/11/D 题意:给定一个图,求图中环的数目 为了消除重复计算,我们要从每个点出发,并将这个点作为环的最小点,再次回到出发点时就变成了环 但是这样依然有重复,会有1条边重复走2次的环,同时还会将大于3的环正向跑一遍逆向跑一遍 所以最后答案需要-m再除2 #include<iostream> #include<cstdio> #include<cstring> #include<s

【题解】 CF11D A Simple Task

[题解] CF11D A Simple Task 传送门 \(n \le 20\) 考虑状态压缩\(dp\). 考虑状态,\(dp(i,j,O)\)表示从\(i\)到\(j\)经过点集\(O\)的路径有多少. \(dp(i,j,O \bigcup i)=\Sigma dp(i,p,O)\),\(j-p\)有一条边. 考虑内存,我们可以认定状态压缩串中\(lowbit(x)\)位是一条路的起点,这样我们直接省掉一维.空间限制卡进去了. 考虑答案怎么统计,就是\((\Sigma (dp(i,j,O)

HUST 1341 A - A Simple Task(哈理工 亚洲区选拔赛练习赛)

A - A Simple Task Time Limit:1000MS    Memory Limit:131072KB    64bit IO Format:%lld & %llu SubmitStatusPracticeHUST 1341 Description As is known to all, lots of birds are living in HUST. A bird has s units of food on the first day, and eats k units

计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task

E. A Simple Task Problem's Link: http://codeforces.com/problemset/problem/558/E Mean: 给定一个字符串,有q次操作,每次操作将(l,r)内的字符升序或降序排列,输出q次操作后的字符串. analyse: 基本思想是计数排序. 所谓计数排序,是对一个元素分布较集中的数字集群进行排序的算法,时间复杂度为O(n),但使用条件很苛刻.首先对n个数扫一遍,映射出每个数字出现的次数,然后再O(n)扫一遍处理出:对于数字ai,

A Simple Task

A Simple Task 就像这道题的题目一样,真的是一个简单的题目,题意就是一句话:给一个数N求符合公式N = O * 2P的 O 和 P. 下面我们就一起看一下题吧. Description Given a positive integer n and the odd integer o and the nonnegative integer p such that n = o2^p. Example For n = 24, o = 3 and p = 3. Task Write a pr

HDU1339_A Simple Task【水题】

A Simple Task Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3987    Accepted Submission(s): 2181 Problem Description Given a positive integer n and the odd integer o and the nonnegative integ