B. pSort
做法:判断连通性,并查集、图论
并查集
#include <iostream>
using namespace std;
static const int N = 110;
int p[N];
int seq[N], d[N];
int n;
void init()
{
for (int i = 1; i <= n; i++)
p[i] = i;
}
int find(int x)
{
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &seq[i]);
init();
for (int i = 1; i <= n; i++)
{
scanf("%d", &d[i]);
if (i - d[i] >= 1)
{
int u = i;
int v = i - d[i];
int pu = find(u), pv = find(v);
if (pu != pv)
p[pu] = pv;
}
if (i + d[i] <= n)
{
int u = i;
int v = i + d[i];
int pu = find(u), pv = find(v);
if (pu != pv)
p[pu] = pv;
}
}
bool flag = true;
for (int i = 1; i <= n; i++)
{
int u = i, v = seq[i];
int pu = find(u), pv = find(v);
if (pu != pv)
flag = false;
}
puts(flag ? "YES" : "NO");
return 0;
}
Floyed
#include <bits/stdc++.h>
using namespace std;
static const int N = 100 + 10;
int a[N], d[N];
int n;
int g[N][N];
void floyd()
{
for (int k = 1; k <= n; k++) // 外层控制中间路过的点
{
for (int i = 1; i <= n; i++) //起点
{
for (int j = 1; j <= n; j++) //终点
{
// 更新某个区间上的路径
// g[i][j] =min(g[i][j],g[i][k] + g[k][j]);
g[i][j]|=(g[i][k]&g[j][k])|(g[i][k]&g[k][j]);
}
}
}
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= n; i ++)
g[i][i] = 1;
for (int i = 1; i <= n; i++)
{
scanf("%d", &d[i]);
if(i - d[i] >= 1)
{
// 合并
g[i][i-d[i]] = 1;
}
if(i + d[i] <= n) g[i][i + d[i]] = 1;
}
floyd();
bool flag = true;
for (int i = 1; i <= n; i++)
{
if(g[i][a[i]]==0) flag = false;
}
puts(flag ? "YES" : "NO");
return 0;
}