题目大意:给你一张无向图
G
(
V
,
E
)
,
∣
V
∣
=
n
G(V,E),|V|=n
G(V,E),∣V∣=n,满足存在整数序列
{
a
n
}
\{a_n\}
{an},使得:
∀
1
≤
x
<
y
≤
n
,
∃
(
x
,
y
)
∈
V
⇐
⇒
a
x
>
a
y
\forall1\le x<y\le n,\exist(x,y)\in V\Leftarrow\Rightarrow a_x>a_y
∀1≤x<y≤n,∃(x,y)∈V⇐⇒ax>ay
成立。现在问有多少
S
⊆
V
S\subseteq V
S⊆V,满足:
∀
x
,
y
∈
S
,
̸
∃
(
x
,
y
)
∈
E
∀
x
∉
S
,
∃
(
x
,
y
)
∈
E
⇒
y
∈
S
\forall x,y\in S,\not\exist(x,y)\in E\\\forall x\notin S,\exist(x,y)\in E\Rightarrow y\in S
∀x,y∈S,̸∃(x,y)∈E∀x∈/S,∃(x,y)∈E⇒y∈S
保证答案小于
2
64
2^{64}
264,
n
≤
1
0
3
n\le10^3
n≤103。
题解:
考虑先用差分约束求出任意一个
G
(
V
,
E
)
G(V,E)
G(V,E)对应的序列
{
a
n
}
\{a_n\}
{an}。考虑
(
x
,
y
)
∈
E
⇐
⇒
a
m
i
n
(
x
,
y
)
>
a
m
a
x
(
x
,
y
)
,
(
x
,
y
)
∉
E
⇐
⇒
a
m
i
n
(
x
,
y
)
≤
a
m
a
x
(
x
,
y
)
(x,y)\in E\Leftarrow\Rightarrow a_{min(x,y)}>a_{max(x,y)},(x,y)\notin E\Leftarrow\Rightarrow a_{min(x,y)}\le a_{max(x,y)}
(x,y)∈E⇐⇒amin(x,y)>amax(x,y),(x,y)∈/E⇐⇒amin(x,y)≤amax(x,y)
假设
S
S
S对应的
{
a
n
}
\{a_n\}
{an}的子序列是
{
b
m
}
\{b_m\}
{bm}。问题转为求有多少子序列对应的点集满足条件。
第一个条件其实是在要求
S
S
S是
G
(
V
,
E
)
G(V,E)
G(V,E)的一个独立集,对于序列等价于:
∀
x
,
y
∈
S
,
x
<
y
,
a
x
≤
a
y
\forall x,y\in S,x<y,a_x\le a_y
∀x,y∈S,x<y,ax≤ay
即
{
b
m
}
\{b_m\}
{bm}是一个非降序列。
第二个条件即
∀
x
∉
S
,
∃
y
∈
S
,
a
m
i
n
(
x
,
y
)
>
a
m
a
x
(
x
,
y
)
\forall x\notin S,\exist y\in S, a_{min(x,y)}>a_{max(x,y)}
∀x∈/S,∃y∈S,amin(x,y)>amax(x,y)
这等价于:
∀
x
∉
S
,
∃
y
∈
S
⇒
(
y
<
x
∧
a
y
>
a
x
)
∨
(
y
>
x
∧
a
x
>
a
y
)
\forall x\notin S,\exist y\in S\Rightarrow(y<x\wedge a_y>a_x)\vee(y>x\wedge a_x>a_y)
∀x∈/S,∃y∈S⇒(y<x∧ay>ax)∨(y>x∧ax>ay)
由于
{
b
m
}
\{b_m\}
{bm}是非降序列,二者显然只可能成立一个。
进一步地说,想要让
x
∉
S
x\notin S
x∈/S满足条件,只需要考虑其在
S
S
S中的前驱后继即可。
因此不难发现,
{
b
m
}
\{b_m\}
{bm}合法,当且仅当(记起对应下标为
{
c
m
}
\{c_m\}
{cm}):
∀
i
∈
[
0
,
m
]
,
b
i
≤
b
i
+
1
∧
(
∀
x
∈
(
c
i
,
c
i
+
1
)
,
a
x
∉
(
b
i
,
b
i
+
1
)
)
\forall i\in[0,m],b_i\le b_{i+1}\wedge \left(\forall x\in(c_i,c_{i+1}),a_x\notin(b_i,b_{i+1}) \right)
∀i∈[0,m],bi≤bi+1∧(∀x∈(ci,ci+1),ax∈/(bi,bi+1))
并且钦定
c
0
=
0
,
c
m
+
1
=
n
+
1
,
a
0
=
−
inf
,
a
n
+
1
=
inf
c_0=0,c_{m+1}=n+1,a_0=-\inf,a_{n+1}=\inf
c0=0,cm+1=n+1,a0=−inf,an+1=inf
令
d
p
i
dp_i
dpi表示子序列末尾在
i
i
i的答案,同时维护
d
i
,
j
=
max
k
∈
(
j
,
i
)
,
a
k
≤
a
i
a
k
d_{i,j}=\max_{k\in(j,i),a_k\le a_i}a_k
di,j=k∈(j,i),ak≤aimaxak
最终
d
p
i
=
∑
j
∈
[
0
,
i
)
,
a
j
≤
a
i
[
a
j
>
d
i
,
j
]
d
p
j
dp_i=\sum_{j\in[0,i),a_j\le a_i}[a_j>d_{i,j}]dp_j
dpi=j∈[0,i),aj≤ai∑[aj>di,j]dpj
时间复杂度 O ( n 2 ) O\left(n^2\right) O(n2)
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define N 1010
#define INF (INT_MAX/10-10)
#define inf (INT_MIN/10+10)
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
struct edges{
int to,pre,wgt;
}e[N*N];int h[N],etop,g[N][N],a[N],inq[N];ull dp[N];queue<int> q;
inline int add_edge(int u,int v,int w) { return e[++etop].to=v,e[etop].pre=h[u],e[etop].wgt=w,h[u]=etop; }
inline int spfa(int s,int n)
{
while(!q.empty()) q.pop();
memset(inq,0,sizeof(int)*(n+1));
rep(i,1,n) a[i]=-1;
a[s]=0,q.push(s),inq[s]=1;
while(!q.empty())
{
int x=q.front();q.pop(),inq[x]=0;
for(int i=h[x],y;i;i=e[i].pre)
if(a[y=e[i].to]<a[x]+e[i].wgt)
{
a[y]=a[x]+e[i].wgt;
if(!inq[y]) inq[y]=1,q.push(y);
}
}
return 0;
}
int main()
{
int n=inn(),m=inn(),s=n+1,u,v;
rep(i,1,m) u=inn()+1,v=inn()+1,g[u][v]=g[v][u]=1;
rep(i,1,n) rep(j,i+1,n)
if(g[i][j]) add_edge(j,i,1);
else add_edge(i,j,0);
rep(i,1,n) add_edge(s,i,0);
spfa(s,n+1),a[0]=inf+1,a[n+1]=INF,dp[0]=1;
rep(i,1,n+1) for(int j=i-1,z=inf;j>=0;j--)
if(a[j]<=a[i]) { if(z<a[j]) dp[i]+=dp[j];z=max(z,a[j]); }
return cout<<dp[n+1]<<endl,0;
}