CF510E: Fox And Dinner

E. Fox And Dinner
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). The i-th fox is ai years old.

They will have dinner around some round tables. You want to distribute foxes such that:

Each fox is sitting at some table.
Each table has at least 3 foxes sitting around it.
The sum of ages of any two adjacent foxes around each table should be a prime number.
If k foxes f1, f2, ..., fk are sitting around table in clockwise order, then for 1 ≤ i ≤ k - 1: fi and fi + 1 are adjacent, and f1 and fk are also adjacent.

If it is possible to distribute the foxes in the desired manner, find out a way to do that.

Input
The first line contains single integer n (3 ≤ n ≤ 200): the number of foxes in this party.

The second line contains n integers ai (2 ≤ ai ≤ 104).

Output
If it is impossible to do this, output "Impossible".

Otherwise, in the first line output an integer m (): the number of tables.

Then output m lines, each line should start with an integer k -=– the number of foxes around that table, and then k numbers — indices of fox sitting around that table in clockwise order.

If there are several possible arrangements, output any of them.

Examples
input
Copy
4
3 4 8 9
output
1
4 1 2 4 3
input
Copy
5
2 2 2 2 2
output
Impossible
input
Copy
12
2 3 4 5 6 7 8 9 10 11 12 13
output
1
12 1 2 3 6 5 12 9 8 7 10 11 4
input
Copy
24
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
output
3
6 1 2 3 6 5 4
10 7 8 9 12 15 14 13 16 11 10
8 17 18 23 22 19 20 21 24
Note
In example 1, they can sit around one table, their ages are: 3-8-9-4, adjacent sums are: 11, 17, 13 and 7, all those integers are primes.

In example 2, it is not possible: the sum of 2+2 = 4 is not a prime number.

奇数偶数建边跑一遍dinic,dfs跑一遍判断哪个桌子

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000;
const int inf = 0x3f3f3f3f;
int level[maxn], n, f, d;
list<int>g[100];
bool vis[300];
int num[300];
bool ok(int x)
{
	for (int i = 2; i <= sqrt(x); ++i)
		if (x%i == 0) return false;
	return true;
}
struct node {
	int to, cap, rev;
	node(int _to, int _cap, int _rev) :to(_to), cap(_cap), rev(_rev) {}
};
vector<node>edge[maxn];
void add_node(int a, int b, int c) {
	//printf("from %d to %d is %d\n", a, b, c);
	edge[a].push_back(node(b, c, edge[b].size()));
	edge[b].push_back(node(a, 0, edge[a].size() - 1));
}
int bfs(int s, int t) {
	memset(level, -1, sizeof(level));
	queue<int>q;
	q.push(s);
	level[s] = 0;
	while (!q.empty()) {
		int tmp = q.front(); q.pop();
		for (int i = 0; i < edge[tmp].size(); i++) {
			node &tmp1 = edge[tmp][i];
			if (level[tmp1.to] == -1 && tmp1.cap > 0) {
				level[tmp1.to] = level[tmp] + 1;
				q.push(tmp1.to);
			}
		}
	}
	return level[t] != -1;
}
int dfs(int s, int t, int flow) {
	if (s == t) return flow;
	int ans = 0;
	for (int i = 0; i < edge[s].size(); i++) {
		node &tmp = edge[s][i];
		if (flow > ans&&tmp.cap > 0 && level[tmp.to] == level[s] + 1) {
			int d = dfs(tmp.to, t, min(tmp.cap, flow - ans));
			if (d > 0) {
				tmp.cap -= d;
				edge[tmp.to][tmp.rev].cap += d;
				ans += d;
			}
		}
	}
	if (ans == 0)
		level[s] = -1;
	return ans;
}
int dinic(int s, int t) {
	int ans = 0, tf;
	while (bfs(s, t))
		while (tf = dfs(s, t, inf))
			ans += tf;
	return ans;
}
int t, s,a[300];
void dfs1(int u, int k) {
	if (vis[u])return;			
	g[k].push_back(num[u]);
	vis[u] = 1;
	for (node i : edge[u]) {
		if (i.to == t || i.to == s)continue;
		if (a[num[u]] & 1 && i.cap == 0 && !vis[i.to]) {//网络流跑完之后,边的值会变为0,反向边的值会变为以前正向边的值
			dfs1(i.to, k);
		}
		else if (!(a[num[u]] & 1) && i.cap == 1 && !vis[i.to]) {
			dfs1(i.to, k);
		}
	}
}
int main()
{
	int b, c;
	scanf("%d", &n);	
	t=n+2;//终点
	s=n+1;//起点
	vector<int>jp[2];
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		jp[a[i] & 1].push_back(a[i]);
		if (a[i] & 1)num[jp[1].size() - 1] = i;//判断在jp数组中的数字在a数组的相对位置
		else num[jp[0].size() - 1 + n / 2] = i;//
	}
	if (jp[0].size()!=jp[1].size()) {//如果不对称,则不可能
		printf("Impossible\n");
		return 0;
	}
	int cnt = 0;
	for (int i = 0; i < jp[1].size(); i++) {
		//cout << jp[1][i] <<' '<<num[i]<< endl;
		for (int j = 0; j < jp[0].size(); j++) {
			if (ok(jp[1][i] + jp[0][j]))add_node(i, j + n/2, 1);
		}
	}
	for (int i = 0; i < jp[0].size(); i++) {
		add_node(s, i, 2);
		add_node(i + n / 2, t, 2);
	}
	if (dinic(s, t) == n) {
		cnt = 0;
		for (int i = 0; i < n; i++) {
			if (vis[i])continue;
			dfs1(i, cnt++);
		}
		cout << cnt << endl;
		for (int i = 0; i < cnt; i++) {
			printf("%d ", g[i].size());
			for (int j : g[i]) printf("%d ", j);
			cout << endl;
		}
	}else printf("Impossible\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/NEONwuwu/article/details/83587945
Fox