HDU 5952

HDU 5952 Counting Cliques

题意:给一个图,给出一个值s,问这个图里面有多少个s条边的完全图。

题解:直接dfs,因为每个点最多只有20个出度,只是在记录时需要单向记录,dfs的时候也就从前往后扫了。现在终于知道当时T掉的原因了。。。原来记录点时set改成数组就不会超时了。纪念一发。

正确代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
int n,m,S,ans,cnt;
int a[105][105];
vector<int> g[105];
int s[1005];
void dfs(int u){
    if(cnt==S){
        ans++;
        return;
    }
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        int flag=0;
        for(int j=1;j<=cnt;j++){
            if(a[v][s[j]]==0){
                flag=1;
                break;
            }
        }
        if(flag==0){
            cnt++;
            s[cnt]=v;
            dfs(v);
            cnt--;
        }
    }
    return;
}
int main(){
    int t; scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&m,&S);
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
            g[i].clear();
        ans=0; cnt=0;

        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            a[x][y]=1;
            a[y][x]=1;
            if(x>y) swap(x,y);
            g[x].push_back(y);
        }
        for(int i=1;i<=n;i++){
            cnt=0;
            s[++cnt]=i;
            dfs(i);
        }
        printf("%d\n",ans);
    }

    return 0;
}

Psong

T掉的代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
int n,m,S,ans;
int a[1005][1005];
int vis[1005];
vector<int> g[1005];
set<int> s;
void dfs(int u){
    s.insert(u);
    if(s.size()==S){
        ans++;
        s.erase(u);
        return;
    }
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        set<int>::iterator it;
        int flag=0;
        for(it=s.begin();it!=s.end();it++){
            if(a[v][*it]==0){
                flag=1;
                break;
            }
        }
        if(flag==0){
            dfs(v);
        }
    }
    s.erase(u);
    return;
}
int main(){
    int t; scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&m,&S);
        memset(vis,0,sizeof(vis));
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
            g[i].clear();
        s.clear();
        ans=0;

        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            a[x][y]=1;
            a[y][x]=1;
        }
        for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++){
            if(a[i][j]==1)
                g[i].push_back(j);
        }

        for(int i=1;i<=n;i++)
            if(!vis[i]) dfs(i);
        printf("%d\n",ans);
    }

    return 0;
}

Psong

时间: 2024-12-30 03:42:53

HDU 5952的相关文章

HDU 5952 [DFS]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=5952] 题意:给出一张无向图,然后判断这张图中一共有多少个不同的大小为S的完全图,并且保证每个点的度不大于20. 题解:好吧,比赛的时候想太多了,结果时间刚不住,TTTT.正解其实很简单,就一个DFS.每次建立DFS(u),表示u在的大小为S的完全图个数,为了保证不重复,我们只建立单向边.每层DFS的时候,取一个点,当且仅的这个点与之前的所有点选过的点有边相连(神优化).总复杂度是100 * 10

Counting Cliques HDU - 5952 单向边dfs

题目:题目链接 思路:这道题vj上Time limit:4000 ms,HDU上Time Limit: 8000/4000 MS (Java/Others),且不考虑oj测评机比现场赛慢很多,但10月5号的计蒜客重现赛只给了1000ms确实有点过分吧,好久没有做这种简单dfs做到自闭了,,,题目并不难,注意剪枝就好了,建图时建标号小的点指向标号大的点的单向边,这样按标号从小到大搜一遍就好了,完全图的任意两个点都要有边,按点的标号搜到第n-s+1个点,因为后面所有的点加起来都组不成点数为s的完全子

HDU 5952 Counting Cliques -暴力

现场赛手速三题,这题一直没写. 直接暴力,注意点只有一个!单向建边,从小点到大点. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 struct edge 6 { 7 int to; 8 int next; 9 }E[1011]; 10 int head[111]; 11 bool e[111][111]; 12 int tot; 13 int

HDU 5952 Counting Cliques(dfs)

Counting Cliques Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1855    Accepted Submission(s): 735 Problem Description A clique is a complete graph, in which there is an edge between every pai

HDU - 5952 Counting Cliques(DFS)

A clique is a complete graph, in which there is an edge between every pair of the vertices. Given a graph with N vertices and M edges, your task is to count the number of cliques with a specific size S in the graph. InputThe first line is the number

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

[hdu 2102]bfs+注意INF

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的--把INF改成INF+INF就过了. #include<bits/stdc++.h> using namespace std; bool vis[2][15][15]; char s[2][15][15]; const int INF=0x3f3f3f3f; const int fx[]={0,0,1,-1};