省选模拟2
T1
题目描述
题解
咕咕咕
T2
题目描述
题解
咕咕咕
T3
题解
由于具有一一对应的关系,所以将图转换为序列。
1,独立集
对应在序列中, 一定是上升子序列
2,覆盖集
对应在序列中,那么没被选择在覆盖集中的点一定与覆盖集中至少一个点连有边。那么该点要么比前面选择的点小,要么比后面选择的点大
于是考虑dp解决,类似于求最长上升子序列,不过转移要满足两个条件
代码
#include<bits/stdc++.h>
#define M 1009
using namespace std;
const int mod=1e9+7;
int read(){
int f=1,re=0;char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-'){f=-1,ch=getchar();}
for(;isdigit(ch);ch=getchar()) re=(re<<3)+(re<<1)+ch-'0';
return re*f;
}
int n,m,num[M],f[M];
bool bj[1009][1009];
signed main(){
//freopen("senritsu.in","r",stdin);
//freopen("senritsu.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
if(x>y) swap(x,y);
bj[x][y]=1;
num[x]++;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(!bj[i][j]) num[j]++;
// for(int i=1;i<=n;i++) printf("%d ",num[i]);
// printf("\n");
num[0]=-1,f[0]=1;
num[n+1]=n+1;
for(int i=1;i<=n+1;i++){
int maxn=-2;
for(int j=i-1;j>=0;j--){
if(num[j]>maxn&&num[j]<num[i]) f[i]=(f[i]+f[j])%mod;
if(num[j]<num[i]) maxn=max(maxn,num[j]);
}
}
// for(int i=1;i<=n;i++) printf("%d ",f[i]);
// printf("\n");
printf("%d\n",f[n+1]%mod);
return 0;
}