gym补题

挂机四个半小时。。。

D effective network

构造题

题意

首先从这个无向图中选出来q个点,然后这q个点之间任意两点之间的距离不能超过q-k

题解

比赛的时候用最短路来维护任意两点之间的距离,然后判断。
因为最短路的时间复杂度为\(O(n^2log(n))\)的预处理,然后二分的寻找q值, \(O(n^3)\)的时间复杂度的寻找判断。结果一直T。。。

后来看了解答。利用了一个性质:
若原来的图中存在一个解,那么整张图也满足原来的性质。

如果对于x个点(x<=n) 存在x-k>=max, 那么x增加一个点。那么最大的距离最大为max+1。那么 (x+1)-k>=(max+1) 依然成立。所以增加到n也是成立的。并且再实际情况中 max并不一定会增加1。这时考虑最差的情况。

然后用bfs对每一个点判断就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5000+10;
int d[maxn];
bool vis[maxn];
vector<int> G[maxn];
int n, m, k;
void init(){
for(int i=0; i<maxn; i++) G[i].clear();
}
int bfs(int u){
memset(vis, 0, sizeof(vis));
memset(d, 0, sizeof(d));
vis[u] = true;
queue<int> q;
q.push(u);
while(!q.empty()){
int temp = q.front();
q.pop();
for(int i=0; i<G[temp].size(); i++){
int v = G[temp][i];
if(vis[v]) continue;
else{
d[v] = d[temp]+1;
vis[v] = true;
q.push(v);
}
}
}
int max_depth = -1;
for(int i=1; i<=n; i++){
max_depth = max(max_depth, d[i]);
}
return max_depth;
}
int main(){
while(cin>>n>>m>>k){
init();
int u, v;
for(int i=0; i<m; i++){
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
int ans = -1;
for(int i=1; i<=n; i++){
int temp = bfs(i);
ans = max(ans, temp);
}
if(ans<=n-k){
cout<<n<<endl;
for(int i=1; i<=n; i++){
i == 1?cout<<1:cout<<" "<<i;
}
cout<<endl;
}
else cout<<0<<endl;
}
return 0;
}

后来发现直接判断规模为n的思想是真的非常的重要啊!
用dij堆优化也能过,用了3837ms,前面的bfs用了1419ms.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5000+10;
const int maxm = 3e4+10;
const int INF = 0x3f3f3f3f;
int dis_all[maxn][maxn];
bool vis[maxn];
int dis[maxn];
int n, m, k;
struct Node{
int v, cost;
Node(int _v = 0, int _cost = 0):v(_v), cost(_cost){}
};
struct qnode{
int v, c;
qnode(int _v=0, int _c=0):v(_v), c(_c){}
bool operator < (const qnode &r) const {
return c>r.c;
}
};
vector<Node> G[maxn];
void init(){
for(int i=0; i<maxn; i++) G[i].clear();
}
void dij(int s){
memset(vis, 0, sizeof(vis));
for(int i=0; i<maxn; i++) dis[i] = INF;
priority_queue<qnode> pq;
dis[s] = 0;
pq.push(qnode(s, 0));
qnode temp;
while(!pq.empty()){
temp = pq.top();
pq.pop();
int u = temp.v;
if(vis[u]) continue;
vis[u] = true;
for(int i=0; i<G[u].size(); i++){
Node e = G[u][i];
int v = e.v;
int cost = e.cost;
if(!vis[v] && dis[v]>dis[u]+cost){
dis[v] = dis[u]+cost;
pq.push(qnode(v, dis[v]));
}
}
}
}
int main(){
ios :: sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(cin>>n>>m>>k){
init();
for(int i=0; i<m; i++){
int u, v;
cin>>u>>v;
G[u].push_back(Node{v, 1});
G[v].push_back(Node{u, 1});
}
int ans = -1;
for(int i=1; i<=n; i++){
dij(i);
for(int j=1; j<=n; j++){
dis_all[i][j] = dis[j];
ans = max(ans, dis[j]);
}
}
bool flag = true;
if(n-k<ans) flag = false;
if(!flag){
cout<<0<<endl;
}
else{
cout<<n<<endl;
for(int i=1; i<=n; i++){
i == 1?cout<<1:cout<<" "<<i;
}
cout<<endl;
}
}
return 0;
}

未解决的问题

文章目录
  1. 1. D effective network
    1. 1.1. 题意
    2. 1.2. 题解
  2. 2. 未解决的问题
{{ live2d() }}