hdu1530 求最大团

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1530

求最大团裸题。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int n;
int mp[55][55],mark[500];
int cn,maxx;
//没优化,跑9000+ms
int t=0;

void dfs(int x)  //dfs(1);
{
    if(x>n)
    {
        maxx=cn;
        return;
    }
    int flag=1;
    for(int i=1; i<x; i++)
    {
        if(mark[i]&&!mp[x][i])
        {
            flag=0;
            break;
        }
    }
    if(flag)
    {
        cn++;
        mark[x]=1;
        dfs(x+1);
        cn--;
    }
    if(cn+n-x+1>maxx)  ///这句话看了好久都没懂是什么意思
    {
        mark[x]=0;
        dfs(x+1);
    }
}

int main()
{
    while(scanf("%d",&n)==1 && n)
    {
        memset(mp,0,sizeof(mp));
        memset(mark,0,sizeof(mark));
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                scanf("%d",&mp[i][j]);
        cn=maxx=0;
        dfs(1);
        printf("%d\n",maxx);
    }
    return 0;
}

模板2:

#include<cstdio>
#include<cstring>
const int N=1010;

//最大团模板
bool a[N][N];//a为图的邻接表(从1开始)
int cnt[N],group[N],vis[N];//cnt[N]表示当前最大团的节点数,group[N]用以寻找一个最大团集合
int n,m,ans;//ans表示最大团
//dfs(i,1);
bool dfs(int u,int pos)//u为当从前顶点开始深搜,pos为深搜深度(即当前深搜树所在第几层的位置)
{
    int i,j;
    for(i=u+1; i<=n; i++)//按递增顺序枚举顶点
    {
        if(cnt[i]+pos<=ans) return 0;//剪枝
        if(a[u][i])
        {
            //与目前团中元素比较,取 Non-N(i)
            for(j=0; j<pos; j++)
                if(!a[i][vis[j]])
                    break;
            if(j==pos)
            {
                //若为空,则皆与 i 相邻,则此时将i加入到 最大团中
                vis[pos]=i;//深搜层次也就是最大团的顶点数目,vis[pos]=i表示当前第pos小的最大团元素为i(因为是按增顺序枚举顶点 )
                if(dfs(i, pos+1)) return 1;
            }
        }
    }
    if(pos>ans)
    {
        for(i=0; i<pos; i++)
            group[i]=vis[i]; // 更新最大团元素
        ans=pos;
        return 1;
    }
    return 0;
}

void maxclique()//求最大团
{
    ans=-1;
    for(int i=n; i>0; i--)
    {
        vis[0]=i;
        dfs(i,1);
        cnt[i]=ans;
    }
}
int main()
{
    while(scanf("%d",&n)==1 && n)
    {
        if(n==0) break;
        int x,y;
        memset(a,0,sizeof(a));
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                scanf("%d",&a[i][j]);
        maxclique();
        if(ans<0) ans=0;//ans表示最大团
        printf("%d\n",ans);
    }
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

int n,path[61][61],s[61],dp[61],ans;

bool is_clique(const int ed,const int point)
{
    for(int i=1; i<ed; i++)
        if(!path[s[i]][point]) return false;
    return true;
}

void dfs(int depth,int now)
{
    if(depth+n-now+1<=ans||depth+dp[now]<=ans) return;
    for(int i=now; i<=n; i++)
    {
        if(is_clique(depth+1,i))
        {
            s[depth+1]=i;
            dfs(depth+1,i+1);
        }
    }
    if(depth>ans) ans=depth;
}

int main()
{
    while(scanf("%d",&n)==1 && n)
    {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                scanf("%d",&path[i][j]);
        memset(dp,0,sizeof(dp));
        ans=0;
        dp[n]=1;
        for(int i=n-1; i>=1; i--)
        {
            s[1]=i;
            dfs(1,i+1);
            dp[i]=ans;
        }
        printf("%d\n",dp[1]);
    }
    return 0;
}
时间: 2024-11-10 00:51:30

hdu1530 求最大团的相关文章

Codeforces Round #533 (Div. 2)E. Helping Hiasat_求最大独立子集转换求最大团

题目链接:E. Helping Hiasat 题解:把夹在同一段1里面的人互相连边,然后问题就转换为求最大独立子集的大小,最大独立子集大小等于补图的最大团.最大图不会的可以看这篇博客,我也是看这个的 #include<bits/stdc++.h> #include<iostream> #include<string> #include<cstring> #include<algorithm> #define pb push_back #defin

HDU1530(最大团)

Given a graph G(V, E), a clique is a sub-graph g(v, e), so that for all vertex pairs v1, v2 in v, there exists an edge (v1, v2) in e. Maximum clique is the clique that has maximum number of vertex. 问题描述:团就是最大完全子图. 给定无向图G=(V,E).如果UV,且对任意u,vU 有(u,v)  E

HDU 5277 YJC counts stars (二维平面图求最大团)

题目链接:传送门 题意: 感觉这次读题特别重要啊"这些点满足任意三点不共线.他把一些点用线段连起来了,但是任意两条线段不会在端点以外相交"这是题目给的原话,但是比赛的时候一直没有用...然后就SB了,因为平面图两两相连而且不相交的点集最大就为4,那么就可以分别来考虑了. 首先考虑最大为4的情况,分别枚举两条边,如果这两条边没有公共点,而且顶点两两相连那么就是一个符合的. 如果最大为3的话,那么就可以枚举一条边,然后再枚举点就可以了. 如果最大为2,就输出边数.最大为1的话就输出点的个数

HDU1530 最大团 模板

Maximum Clique Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4114    Accepted Submission(s): 2175 Problem Description Given a graph G(V, E), a clique is a sub-graph g(v, e), so that for all

(最大团) poj 3692

L - Kindergarten Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3692 Description In a kindergarten, there are a lot of kids. All girls of the kids know each other and all boys also know each ot

Poj_2771 Guardian of Decency -最大团

题目: 找出不会恋爱的人的最大独立集. 分析:一眼看下去以为是最大独立集,但是题目给定的边是不会恋爱的边,所以想想会发现其实求最大团. 吐槽:虽然看到500个点,但我没用邻接表,因为求补图的话边会很多,是个稠密图. /************************************************ Author :DarkTong Created Time :2016/8/1 10:14:42 File Name :Poj_2771.cpp *******************

CF839E Mother of Dragons 最大团 Bron-Kerbosch算法

题意简述 给你一个\(n\)个节点的无向图\(G=\{V,E\}\)的邻接矩阵\(g\)和每个点的点权为\(s_i\),且\(\sum_{i=1}^n s_i = K\),要你求出\(\mathrm{max} \{ \sum_{u,v \in E} s_u \times s_v\}\) 做法 设两个不相邻的点\(u\),\(v\)的点权为\(s_u\)和\(s_v\),令\(a_u = \sum_{g[u][i]=1} s_i, a_v=\sum_{g[v][i]=1} s_i\),此时这对点\

《算法概论》第八章的一些课后题目 关于NP-Complete Problem

8.3 STINGY SAT STINGY SAT is the following problem: given a set of clauses (each a disjunction of literals) and an integer k, find a satisfying assignment in which at most k variables are true, if such an assignment exists. Prove that STINGY SAT is N

poj1419Graph Coloring

Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4379   Accepted: 1985   Special Judge Description You are to write a program that tries to find an optimal coloring for a given graph. Colors are applied to the nodes of the graph and the o