题型:图论
题意:若干个区间,求最多的区间数,并且这些区间都互不相交。
分析:
相交的区间建边,然后取反图求最大独立集。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
const int M=32;
class Maxclique {
int n,big,res[M],c[M],v[M],rr[M];
bool bb,mat[M][M];
public:
void init(int x) {
n=x;
big=0;
mt(mat,0);
}
int getvalue() {
return big;
}
void getsolution() {
for(int i=0; i<big; i++) {
printf("%d ",res[i]);
}
}
void add(int x,int y) {
mat[x][y]=true;
mat[y][x]=true;
}
void inv() {
for(int i=0; i<=n; i++) {
for(int j=0; j<=n; j++) {
mat[i][j]=!mat[i][j];
}
}
}
void clique(int num,int u[],int len) {
int i,j,vn,v[M];
if(num) {
if(len+c[u[0]]<=big) return ;
for(i=0; i<num+len-big&&i<num; i++) {
for(j=i+1,vn=0; j<num; j++) if (mat[u[i]][u[j]]) v[vn++]=u[j];
rr[len]=u[i];
clique(vn,v,len+1);
if(bb) return;
}
} else if (len>big) {
big=len;
for (i=0; i<len; i++) res[i]=rr[i];
bb=true;
}
}
void maxclique() {
int i,j,vn;
for(c[i=n-1]=0; i>=0; i--) {
for(vn=0,j=i+1; j<n; j++) if (mat[i][j]) v[vn++]=j;
bb=false;
rr[0]=i;
clique(vn,v,1);
c[i]=big;
}
}
} gx;
struct IN{
int s,f;
}g[32];
bool inside(int i,int j){
int ax=g[i].s;
int ay=g[i].f;
int bx=g[j].s;
int by=g[j].f;
if(ax>bx){
swap(ax,bx);
swap(ay,by);
}
if(bx<ay) return true;
return false;
}
int main(){
int t,n,a,b;
while(~scanf("%d",&t)){
while(t--){
n=0;
while(scanf("%d%d",&a,&b),a|b){
g[n].s=a;
g[n].f=b;
n++;
}
gx.init(n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(inside(i,j)){
gx.add(i,j);
}
}
}
gx.inv();
gx.maxclique();
printf("%d\n",gx.getvalue());
}
}
return 0;
}