赞
踩
有
3
3
3个Takahashi,他们帽子的颜色分别为
S
1
,
S
2
,
S
3
S_1,S_2,S_3
S1,S2,S3。
我们现在想通过正好
1
0
18
10^{18}
1018次操作,使得
S
i
=
T
i
S_i=T_i
Si=Ti。
每次操作如下:
试问能否达成目标?
S
1
S
2
S
3
S_1~S_2~S_3
S1 S2 S3
T
1
T
2
T
3
T_1~T_2~T_3
T1 T2 T3
如果能达成目标,输出Yes
;否则,输出No
。
R G B
R G B
Yes
本题情况不多,可以手动枚举所有可能的情况,最终发现所有
S
i
=
T
i
S_i=T_i
Si=Ti或者所有
S
i
≠
T
i
S_i\ne T_i
Si=Ti时输出Yes
,否则输出No
。
#include <cstdio>
using namespace std;
int main()
{
char a, b, c, d, e, f;
scanf("%c %c %c %c %c %c", &a, &b, &c, &d, &e, &f);
puts(((a == d) + (b == e) + (c == f)) == 1? "No": "Yes");
return 0;
}
给定由
N
N
N个点、
M
M
M条边组成的简单无向图。第
i
i
i条边连接顶点
U
i
U_i
Ui和
V
i
V_i
Vi。
求图中从
S
S
S到
T
T
T、长度为
K
K
K且经过顶点
X
X
X偶数次的路径的数量,对
998244353
998244353
998244353取模。
2
≤
N
≤
2000
2\le N\le 2000
2≤N≤2000
1
≤
M
≤
2000
1\le M\le 2000
1≤M≤2000
1
≤
K
≤
2000
1\le K\le 2000
1≤K≤2000
1
≤
S
,
T
,
X
≤
N
1\le S,T,X\le N
1≤S,T,X≤N
X
≠
S
,
X
≠
T
X\ne S,X\ne T
X=S,X=T
1
≤
U
i
<
V
i
≤
N
1\le U_i<V_i\le N
1≤Ui<Vi≤N
(
U
i
,
V
i
)
≠
(
U
j
,
V
j
)
(U_i,V_i)\ne(U_j,V_j)
(Ui,Vi)=(Uj,Vj)(
i
≠
j
i\ne j
i=j)
N
M
K
S
T
X
N~M~K~S~T~X
N M K S T X
U
1
V
1
U_1~V_1
U1 V1
⋮
\vdots
⋮
U
N
V
N
U_N~V_N
UN VN
输出图中从 S S S到 T T T、长度为 K K K且经过顶点 X X X偶数次的路径的数量,对 998244353 998244353 998244353取模。
4 4 4 1 3 2
1 2
2 3
3 4
1 4
4
有 4 4 4条符合条件的路径:
注意 X = 2 X=2 X=2必须出现偶数次。
6 5 10 1 2 3
2 3
2 4
4 6
3 6
1 5
0
这张图没有连通。
10 15 20 4 4 6 2 6 2 7 5 7 4 5 2 4 3 7 1 7 1 4 2 9 5 10 1 3 7 8 7 9 1 6 1 2
952504739
注意对 998244353 998244353 998244353取模。
我们先不考虑
X
X
X的限制条件,则可以令
d
p
(
i
,
j
)
=
\mathrm{dp}(i,j)=~
dp(i,j)= 第
i
i
i步走到
j
j
j的可能数,则因为点
j
j
j可以从
G
j
G_j
Gj中的任意一点走过来(
G
G
G为邻接表存储),所以我们得到
d
p
(
i
,
j
)
=
∑
k
=
1
∣
G
j
∣
d
p
(
i
−
1
,
G
j
k
)
\mathrm{dp}(i,j)=\sum_{k=1}^{|G_j|} \mathrm{dp}(i-1,{G_j}_k)
dp(i,j)=k=1∑∣Gj∣dp(i−1,Gjk)
再考虑
X
X
X必须是偶数的情况,令
d
p
(
i
,
j
,
k
)
=
\mathrm{dp}(i,j,k)=~
dp(i,j,k)= 第
i
i
i步走到
j
j
j且
X
X
X的出现次数除以
2
2
2的余数为
k
k
k的情况,则每次额外判断
G
j
k
{G_j}_k
Gjk是否等于
X
X
X即可。
D
P
\mathrm{DP}
DP状态转移方程详见代码。
注意:代码中运用了滚动表的优化,可以节省空间,当然也可以使用普通写法。
#include <cstdio> #include <vector> #define maxn 2005 #define MOD 998244353 using namespace std; inline void mod(int& x) { if(x >= MOD) x -= MOD; } vector<int> G[maxn]; int dp[2][maxn][2]; int main() { int n, m, k, s, t, x; scanf("%d%d%d%d%d%d", &n, &m, &k, &s, &t, &x); x --; while(m--) { int u, v; scanf("%d%d", &u, &v); G[--u].push_back(--v); G[v].push_back(u); } dp[0][--s][0] = 1; for(int i=1; i<=k; i++) { bool c = i & 1, p = i & 1 ^ 1; for(int v=0; v<n; v++) { dp[c][v][0] = dp[c][v][1] = 0; for(int u: G[v]) mod(dp[c][v][0] += dp[p][u][u == x]), mod(dp[c][v][1] += dp[p][u][u != x]); } } printf("%d\n", dp[k & 1][--t][0]); return 0; }
令 d i s [ S ] [ j ] = \mathrm{dis}[S][j]=~ dis[S][j]= 于点 j j j结束的good path with respest to S的最短长度,跑一遍 BFS \text{BFS} BFS即可。具体实现时可将 S S S按位压缩为二进制,加快运算速度。
#include <cstdio> #include <queue> #define INF 2147483647 #define maxn 17 using namespace std; using ULL = unsigned long long; int dis[1 << maxn][maxn]; vector<int> G[maxn]; int main() { int n, m; scanf("%d%d", &n, &m); while(m--) { int u, v; scanf("%d%d", &u, &v); G[--u].push_back(--v); G[v].push_back(u); } queue<ULL> q; for(int i=0; i<n; i++) dis[1 << i][i] = 1, q.push(1ULL<<i+32^i); while(!q.empty()) { ULL pkg = q.front(); q.pop(); int st = pkg >> 32ULL, v = pkg & 0x7fffffff; int nd = dis[st][v] + 1; for(int u: G[v]) { int nst = st ^ (1 << u); if(dis[nst][u] == 0) { dis[nst][u] = nd; q.push(ULL(nst) << 32ULL ^ u); } } } long long ans = 0LL; for(int i=1, lim=1<<n; i<lim; i++) { int cur = INF; for(int j=0; j<n; j++) if(dis[i][j] > 0 && dis[i][j] < cur) cur = dis[i][j]; ans += cur; } printf("%lld\n", ans); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。