CodeForces 510E Fox And Dinner

CodeForces 510E

素数打表+最大流+最大流打印路径

注意到ai (2 ≤ ai ≤ 104).那么题中的所有素数一定是一个奇数和一个偶数的和。那么所有的桌子都是偶环

将所有的偶数点连接超级源点,奇数点连接超级汇点,容量都为2.将所有的偶数点与奇数点间建容量为1的边,若满流,则可以满足条件

画个图可以知道这样建图是正确的→_→,怎么能想到这一点呢?弱不造

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=208;
const int maxm=20008;
const int INF=0x7f7f7f7f;
int sb[maxn],sx[maxn];
bool pri[maxm];
void shit()
{
	memset(pri,false,sizeof(pri));
	pri[2]=true;
	int i,j,x;
	for(i=3;i<=20000;i++)
	{
		x=sqrt(i);
		for(j=2;j<=x;j++)
			if(i%j==0)
				break;
		if(j>x)	pri[i]=true;
	}
}
struct fuck{
	int u,v,cap,next;
}edge[maxm];
int tol;
int head[maxn];
void init()
{
	tol=0;
	memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)
{
	edge[tol].u=u;
	edge[tol].v=v;
	edge[tol].next=head[u];
	edge[tol].cap=w;
	head[u]=tol++;
	edge[tol].v=u;
	edge[tol].u=v;
	edge[tol].cap=0;
	edge[tol].next=head[v];
	head[v]=tol++;
}
bool vis[maxn];
int dep[maxn],gap[maxn];
void bfs(int sour,int sink)
{
	queue<int>	q;
	memset(vis,false,sizeof(vis));
	memset(dep,-1,sizeof(dep));
	memset(gap,0,sizeof(gap));
	q.push(sink);
	dep[sink]=0;gap[0]=1;vis[sink]=true;
	int u,v,i;
	while(!q.empty())
	{
		u=q.front();q.pop();
		for(i=head[u];i!=-1;i=edge[i].next)
		{
			v=edge[i].v;
			if(!vis[v]&&edge[i].cap==0)
			{
				vis[v]=true;
				dep[v]=dep[u]+1;
				q.push(v);
				gap[dep[v]]++;
			}
		}
	}
}
int cur[maxn],S[maxm];
int last;
int sap(int sour,int sink)
{
	bfs(sour,sink);
	int max_flow=0,i,u;
	for(i=0;i<=last;i++)	cur[i]=head[i];
	int top=0;
	u=sour;
	while(dep[sour]<last)
	{
		if(u==sink)
		{
			int temp=INF,inser;
			for(i=0;i<top;i++)
			{
				if(edge[S[i]].cap<temp)
				{
					temp=edge[S[i]].cap;
					inser=i;
				}
			}
			for(i=0;i<top;i++)
			{
				edge[S[i]].cap-=temp;
				edge[S[i]^1].cap+=temp;
			}
			max_flow+=temp;
			top=inser;
			u=edge[S[top]].u;
		}
		if(u!=sink&&gap[dep[u]-1]==0)	break;
		for(i=cur[u];i!=-1;i=edge[i].next)
			if(edge[i].cap>0&&dep[u]==dep[edge[i].v]+1)
				break;
		if(i!=-1)
		{
			cur[u]=i;
			S[top++]=i;
			u=edge[i].v;
		}
		else
		{
			int mi=last;
			for(i=head[u];i!=-1;i=edge[i].next)
			{
				if(edge[i].cap==0)	continue;
				if(mi>dep[edge[i].v])
				{
					mi=dep[edge[i].v];
					cur[u]=i;
				}
			}
			--gap[dep[u]];
			dep[u]=mi+1;
			++gap[dep[u]];
			if(u!=sour)	u=edge[S[--top]].u;
		}
	}
	return max_flow;
}
int zhan[maxn];
int lin[maxn];
int sum;
int li[maxn];
int dian[maxn];
int w[maxn];
void dfs(int u,int idx)
{
	vis[u]=true;
	sum++;
	int i;
	if(u<=idx)
	{
		for(i=head[u];i!=-1;i=edge[i].next)
			if(edge[i].cap==0&&edge[i].v!=0&&!vis[edge[i].v])
			{
				lin[u]=edge[i].v;
				dfs(edge[i].v,idx);
			}
	}
	else
	{
		for(i=head[u];i!=-1;i=edge[i].next)
			if(edge[i].cap>0&&edge[i].v!=last-1&&!vis[edge[i].v])
			{
				lin[u]=edge[i].v;
				dfs(edge[i].v,idx);
			}
	}
}
int main()
{
	int i,j,n,m,x;
	shit();
	while(scanf("%d",&n)==1)
	{
		int idx,idb;
		idx=idb=0;
		init();
		for(i=1;i<=n;i++)
		{
			scanf("%d",&x);
			if(x&1)
			{
				sb[++idb]=x;
				dian[idb]=i;
			}
			else
			{
				sx[++idx]=x;
				w[idx]=i;
			}
		}
		for(i=1;i<=idx;i++)
			for(j=1;j<=idb;j++)
			{
				if(pri[sx[i]+sb[j]])
					addedge(i,j+idx,1);
			}
		int sour,sink;
		sour=0;sink=n+1;
		for(i=1;i<=idx;i++)
			addedge(sour,i,2);
		for(i=1;i<=idb;i++)
			addedge(i+idx,sink,2);
		last=n+2;
		int ans=sap(sour,sink);
		if(ans!=n)	printf("Impossible\n");
		else
		{
			ans=0;
			int id=0;
			memset(vis,false,sizeof(vis));
			memset(lin,-1,sizeof(lin));
			for(i=1;i<=idx;i++)
			{
				if(!vis[i])
				{
					sum=0;
					dfs(i,idx);
					li[id]=i;
					zhan[id++]=sum;
				}
			}
			printf("%d\n",id);
			for(i=0;i<id;i++)
			{
				printf("%d",zhan[i]);
				int pa=li[i];
				while(pa!=-1)
				{
					if(pa<=idx)
						printf(" %d",w[pa]);
					else
						printf(" %d",dian[pa-idx]);
					pa=lin[pa];
				}
				printf("\n");
			}
		}
	}
	return 0;
}
时间: 2024-10-26 05:59:54

CodeForces 510E Fox And Dinner的相关文章

codeforces 510E. Fox And Dinner 网络流

题目链接 给出n个人, 以及每个人的值, 要求他们坐在一些桌子上面, 每个桌子如果有人坐, 就必须做3个人以上. 并且相邻的两个人的值加起来必须是素数.每个人的值都>=2. 由大于等于2这个条件, 可以知道素数都是奇数, 那么很明显就需要一奇一偶相邻这样做, 那么一个桌子上必定有偶数个人. 一个奇数旁边有两个偶数, 一个偶数旁边有两个奇数. 所以可以先判断n是否为偶数, 如果是奇数直接输出不可能. 然后开始奇偶建边, 源点和奇数建边, 权值为2, 因为一个奇数需要和两个偶数匹配: 偶数和汇点建边

Codeforces 512C Fox And Dinner 奇偶建图 网络流

题目链接:点击打开链接 题意: 给定n个人和其权值. 让人坐到任意多张圆形的桌子上使得任意两个相邻的人权值和为素数,且一张桌子至少3个人 输出桌子数和每张桌子坐的人(输出任意一个具体方案) 思路: 首先人的权值都是>=2的,也是就说组合成的素数一定是奇数 奇数 = 奇数+偶数.所以桌子上的人一定是奇偶交错的,而且一张桌子人数是偶数个(即n必须为偶数,一半是奇数,一半是偶数) 由上得:一个奇数要选择2个偶数,一个偶数要被2个奇数选择. 所以得到一个二部图,X集为奇数,Y集为偶数 网络流: 奇数连源

CF510E. Fox And Dinner

CF510E. Fox And Dinner https://codeforces.com/contest/510 分析: 由于\(a_i>2\), 相邻两个数一定一奇一偶,按奇偶建立二分图. 环上每个点度数都为2,因此只需要找是否每个点都能匹配两个. 建图跑dinic即可. 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include

网络流(最大流)CodeForces 512C:Fox And Dinner

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

CodeForces Round #290 Fox And Dinner

而是Div2的最后一题,当时打比赛的时候还不会最大流.自己能够把它写出来然后1A还是很开心的. 题意: 有n个不小于2的整数,现在要把他们分成若干个圈.在每个圈中,数字的个数不少于3个,而且相邻的两个数之和是质数. 分析: 因为每个数都不小于2,所以相加得到的质数一定是奇数,那么在某个圈中,一定是奇偶相间的. 也就是 奇数相邻的两个数是偶数,偶数相邻的两个数是奇数. 所以一个圈中的数字一定是偶数个,所有的输入中也必须是偶数和奇数的个数相同才可能有解. 这转化为了二分图匹配,其中X是奇数,Y是偶数

Codeforces Fox And Dinner(最大流)

抄了个DINIC的模板,然后模拟一下. #include <bits/stdc++.h> using namespace std; const int maxn=80005; const int inf=0x3f3f3f3f; typedef vector<int> vi; typedef vector<vi> vii; bool vis[maxn]; vector<int>odd,even; vii ans; void init(){ for(int i=

CodeForces 388A Fox and Box Accumulation (模拟)

A. Fox and Box Accumulation time limit per test:1 second memory limit per test:256 megabytes Fox Ciel has n boxes in her room. They have the same size and weight, but they might have different strength. The i-th box can hold at most xi boxes on its t

CodeForces 388A Fox and Box Accumulation 贪心

Fox Ciel has n boxes in her room. They have the same size and weight, but they might have different strength. The i-th box can hold at most xi boxes on its top (we'll call xi the strength of the box). Since all the boxes have the same size, Ciel cann

codeforces 510B. Fox And Two Dots 解题报告

题目链接:http://codeforces.com/problemset/problem/510/B 题目意思:给出 n 行 m 列只有大写字母组成的字符串.问具有相同字母的能否组成一个环. 很容易知道要用到深搜.暴力搜索--- 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 7 cons