1.题目描述:
给你一个无向图n个顶点m条边,k个克隆人,他们最多行走(2 * n) / k向上取整个步数,要你安排具体每个机器人行走的方案,题目保证有解
3.解题思路:
考虑DFS+回溯的话,发现正好最多走2*n条边,而k个机器人 ⌈2nk⌉×k≥2n 可以总共遍历点大于 2n。那么直接爆搜一遍记录路径就行。然后注意分配当k特别大时候,剩余的机器人只要停留在原地(即1 1)就行。
4.AC代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define maxn 200100
#define N 1111
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
typedef unsigned long long ull;
vector<int> G[maxn];
bool vis[maxn];
int path[maxn * 2], cnt;
void dfs(int from)
{
vis[from] = 1;
path[++cnt] = from;
for (int i = 0; i < (int)G[from].size(); i++)
{
int to = G[from][i];
if (!vis[to])
{
dfs(to);
path[++cnt] = from; //相当于回溯
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
long _begin_time = clock();
#endif
int n, m, k;
while (~scanf("%d%d%d", &n, &m, &k))
{
cnt = 0;
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++)
G[i].clear();
for (int i = 0; i < m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1);
int maxC = (2 * n + k - 1) / k;
for (int i = 0; i < k; i++)
{
int c = min(maxC, cnt);
if (c)
{
printf("%d", c);
for (int j = 0; j < c && cnt; j++)
printf(" %d", path[cnt--]);
puts("");
}
else
puts("1 1");
}
}
#ifndef ONLINE_JUDGE
long _end_time = clock();
printf("time = %ld ms.", _end_time - _begin_time);
#endif
return 0;
}