poj1419 最大团
本题的意思是求最大团,并且输出路径。
如果用朴素算法时间复杂度太高,如果n是100的话,至少要几秒,要慎用。
还有一个就是用DP记录。时间复杂度要低很多。也可以输出路径。
#include<iostream> using namespace std; const int N=109; int map[N][N]; int sta[N][N],dp[N]; int mx,n; int path[N],x[N];// 取决于是否需要最优解.若需要,还要增加一个path[maxn]数组 int dfs(int ns,int dep) { if(0==ns) { if(dep>mx) { mx=dep; for(int i=0;i<dep;i++) path[i]=x[i];//路径信息2,这个数组必须要 } return 1; } int i,j,k,p,cnt; for(i=0;i<ns;i++) { k=sta[dep][i];cnt=0; if(dep+n-k<=mx)return 0; if(dep+dp[k]<=mx)return 0; x[dep]=k;//路径信息3 for(j=i+1;j<ns;j++) { p=sta[dep][j]; if(map[k][p]) { sta[dep+1][cnt++]=p; } } dfs(cnt,dep+1); } return 0; } void clique() { int i,j,ns; for(mx=0,i=n-1;i>=0;i--) { x[0]=i; //路径信息1 for(ns=0,j=i+1;j<n;j++) if(map[i][j])sta[1][ns++]=j; dfs(ns,1); dp[i]=mx; } } int main() { int t,i,m,a,b; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<=n;i++) { map[i][i]=0; for(int j=i+1;j<=n;j++) map[i][j]=map[j][i]=1; } memset(sta,0,sizeof(sta)); for(i=0;i<m;i++) { scanf("%d%d",&a,&b); map[a-1][b-1]=map[b-1][a-1]=0; } clique(); printf("%d\n",mx); for(i=0;i<mx-1;i++) printf("%d ",path[i]+1); printf("%d\n",path[i]+1); } return 0; }