Problem Statement
The Republic of AtCoder has N cities, called City 1, City 2, ……, City N. Initially, there was a bidirectional road between every pair of different cities, but M of these roads have become unusable due to deterioration over time. More specifically, for each 1≤i≤M, the road connecting City Ui and City Vi has become unusable.
Takahashi will go for a KK-day trip that starts and ends in City 1. Formally speaking, a KK-day trip that starts and ends in City 1 is a sequence of K+1 cities (A0,A1,…,AK) such that A0=AK=1 holds and for each 0≤i≤K−1, Ai and Ai+1 are different and there is still a usable road connecting City Ai and City Ai+1.
Print the number of different K-day trips that start and end in City 1, modulo 998244353. Here, two K-day trips (A0,A1,…,AK) and (B0,B1,…,BK) are said to be different when there exists an i such that Ai≠Bi.
Constraints
- 2≤N≤5000
- 0≤M≤min(N(N−1)2,5000)
- 2≤K≤5000
- 1≤Ui<Vi≤N
- All pairs (Ui,Vi) are pairwise distinct.
- All values in input are integers.
Input
Input is given from Standard Input in the following format:
N M K
U1 V1
::
UM VM
Output
Print the answer.
Sample Input 1 Copy
3 1 4
2 3
Sample Output 1 Copy
4
There are four different trips as follows.
- (1,2,1,2,1)
- (1,2,1,3,1)
- (1,3,1,2,1)
- (1,3,1,3,1)
No other trip is valid, so we should print 44.
Sample Input 2 Copy
3 3 3
1 2
1 3
2 3
Sample Output 2 Copy
0
No road remains usable, so there is no valid trip.
Sample Input 3 Copy
5 3 100
1 2
4 5
2 3
Sample Output 3 Copy
428417047
题目翻译
(N)座城市,每对城市间有双向道路,有(M)条道路无法使用
从城市(1)出发,旅行(K)天,最后一天回到(1)。旅游城市序列(A_0,A_1,...A_k),其中(A_0=A_k=1),共有多少不同旅行方案
(2<=N<=5000)
(M<=min(frac{N*(N-1)}{2},5000))
(2<=K<=5000)
题目解析
首先考虑最简单的做法,令(f[j][i])表示第(i)天在城市(j)
枚举天数(i),和停留的城市(j)进行转移
但题目给出的(M)条边是不可通行的道路,如果枚举所有可行道路,复杂度将达到(O(K*N^2)),不符合数据范围
考虑到(f[j][i]=sum_{k=1}^{n}{f[k][i-1]}-sum_{k不可达}{f[k][i-1]}-f[j][i-1])
(sum_{k=1}^{n}{f[k][i-1]})可以(O(N))求出,(sum_{k不可达}{f[k][i-1]})可以(O(M))求出
总复杂度为(O(K*(N+M)))
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
typedef long long ll;
struct Node{
int next,to;
}edge[10005];
int n,m,k;
int head[5005],num,f[5005][5005],Mod=998244353;
void add(int u,int v){
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
int main(){
int u,v;
cin>>n>>m>>k;
for (int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
memset(f,0,sizeof(f));
f[1][0]=1;
for (int i=1;i<=k;i++){
int sum=0;
for (int j=1;j<=n;j++)
sum=(sum+f[j][i-1])%Mod;
for (int j=1;j<=n;j++){
f[j][i]=(sum-f[j][i-1]+Mod)%Mod;
for (int k=head[j];k;k=edge[k].next){
int v=edge[k].to;
f[j][i]=(f[j][i]-f[v][i-1]+Mod)%Mod;
}
}
}
cout<<f[1][k]<<endl;
}