题目:
题意:
有
n
n
n个区间,当且仅当两个区间的交集不为空,编号才会有边
如此一来会形成一张图
问在图上选择一些边,能使得新图是一棵树的方案数是多少
分析:
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
#define mo 1000000007
using namespace std;
inline LL read()
{
LL s=0,f=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {s=s*10+c-'0';c=getchar();}
return s*f;
}
struct in{
int l,r;
}e[2005];
bool cmp(in a,in b) {return a.l<b.l;}
int nex[4005];
int f[2005][4005],mr=0;
int main()
{
freopen("graph.in","r",stdin);
freopen("graph.out","w",stdout);
int n=read();
for(int i=1;i<=n;i++) e[i].l=read(),e[i].r=read(),mr=max(mr,e[i].r);
sort(e+1,e+1+n,cmp);
e[n+1].l=mr+1;
for (int i=1,j=1;i<=n+1;i++) while (j<e[i].l) nex[j]=i-1,j++;
for(int i=0;i<=n;i++)
{
int r=e[i+1].r;
(f[i+1][r]+=1)%=mo;
for(int j=1;j<=mr;j++)
{
(f[i+1][j]+=f[i][j])%=mo;
if(e[i+1].l>j) continue;
if(r<=j) (f[nex[r]][j]+=f[i][j])%=mo;
if(r>j) (f[nex[j]][r]+=f[i][j])%=mo;
}
}
int ans=0;
for(int i=1;i<=mr;i++) (ans+=f[n+1][i])%=mo;
cout<<ans;
return 0;
}