CodeForces 11D A Simple Task (DP解哈密顿路径数目)
D. A Simple Task
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Given a simple graph, output the number of simple cycles in it. A simple cycle is a cycle with no repeated vertices or edges.

Input

The first line of input contains two integers n and m (1 ≤ n ≤ 190 ≤ m) – respectively the number of vertices and edges of the graph. Each of the subsequent m lines contains two integers a and b, (1 ≤ a, b ≤ na ≠ b) indicating that vertices a and b are connected by an undirected edge. There is no more than one edge connecting any pair of vertices.

Output

Output the number of cycles in the given graph.

Sample test(s)
input
4 6
1 2
1 3
1 4
2 3
2 4
3 4
output
7
Note

The example graph is a clique and contains four cycles of length 3 and three cycles of length 4.


题意:

求一个图中(节点个数小于20)长度大于等于三的哈密顿路径数目。


思路:

点数不多,类似TSP,用状压dp解决。

dp[i][j]表示状态为i时,以j结尾的路径条数。

如果下一个点能回到已经走过的一个点中,那么就是一个回路了。

为了避免重复计算,回到的点为走过的最小的点。(这是一个优化,少了枚举最小点这个循环)

长度为2的哈密顿路径会计算到,可以不做处理,最后减去边的条数即可,每个环会算两遍,最后要除以2.


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 205
#define MAXN 100005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;

ll n,m,ans,flag,cnt,tot;
ll mp[20][20],dp[1<<19][19];

int first(int s)
{
    for(int i=0;i<n;i++)
    {
        if(s&(1<<i)) return i;
    }
}
void solve()
{
    ll i,j,t,k,p,u,v,s;
    ans=0;
    tot=(1<<n)-1;
    memset(dp,0,sizeof(dp));
    for(i=0;i<n;i++)
    {
        dp[1<<i][i]=1;
    }
    for(i=1; i<=tot; i++)
    {
        for(j=0; j<n; j++)
        {
            if(dp[i][j]==0) continue ;
            p=first(i);
            for(k=p; k<n; k++)
            {
                if(j==k||mp[j][k]==0) continue ;
                if(i&(1<<k))
                {
                    if(k==p) ans+=dp[i][j];
                }
                else
                {
                    s=i|(1<<k);
                    dp[s][k]+=dp[i][j];
                }
            }
        }
    }
    ans-=m;
    ans/=2;
    printf("%I64d\n",ans);
}
int main()
{
    ll i,j,t;
    while(~scanf("%I64d%I64d",&n,&m))
    {
        memset(mp,0,sizeof(mp));
        ll u,v;
        for(i=1; i<=m; i++)
        {
            scanf("%I64d%I64d",&u,&v);
            u--,v--;
            mp[u][v]=mp[v][u]=1;
        }
        solve();
    }
    return 0;
}


阅读更多
个人分类: dp
想对作者说点什么? 我来说一句

用贪心算法求解哈密顿回路

2009年09月22日 2KB 下载

没有更多推荐了,返回首页

不良信息举报

CodeForces 11D A Simple Task (DP解哈密顿路径数目)

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭