Codeforces 11D A Simple Task (状态压缩DP)

给你N个点和M条边,求当中包含的简单路径的个数。

网上看的题解,其实就是求哈密顿回路数,但是是无向图而且至少由三个点组成。

http://codeforces.com/blog/entry/337

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const ll maxm=1<<19;
ll dp[maxm][20],sum;
int lowbit[maxm];
bool map[20][20];
int n,m,u,v,start;
inline bool bt(int i,int mask)
{
    return mask&(1<<i);
}
inline int cnt(int mask)
{
    int ret=0;
    while(mask) ret+=(mask&1),mask>>=1;
    return ret;
}
void getfirst()
{
    int i;
    for(i=1; i<maxm; i++)
    {
        int mask=i,ret=0;
        while(mask&1^1) ret++,mask>>=1;
        lowbit[i]=ret;
    }
}
ll dfs(int mask,int end)
{
    int j,tmp=cnt(mask);
    ll ans=0;
    if(dp[mask][end]>=0) return dp[mask][end];
    for(j=start; j<n; j++)
        if(j!=end&&bt(j,mask)&&map[j][end]&&(tmp==2||j!=start))
            ans+=dfs(mask^(1<<end),j);
    if(tmp>2&&map[end][start])//当前搜索的end点和起始点相连并且含有3个点以上
        sum+=ans;
    return dp[mask][end]=ans;
}
int main()
{
    int i;
    getfirst();
    memset(dp,-1,sizeof(dp));
    memset(map,0,sizeof(map));
    cin>>n>>m;
    sum=0;
    while(m--)
    {
        cin>>u>>v;
        u--,v--;
        map[u][v]=map[v][u]=1;
    }
    for(i=0; i<n; i++) dp[1<<i][i]=1;
    int maxmask=1<<n;
    for(int mask=0; mask<maxmask; mask++)
        if(cnt(mask)>1)
        {
            start=lowbit[mask];
            for(i=start; i<n; i++)
                if(bt(i,mask)&&map[start][i])
                    dfs(mask,i);
        }
    cout<<sum/2<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值