【Codeforces】512C Fox and Dinner
【解析】欧拉筛法,奇偶分析。建二分图,网络流
[Analysis]
http://blog.csdn.net/qq574857122/article/details/43453087。
所谓的连通块就是指满流了,因为我直接使用剩余流量求网络流。
至于怎样推断满流,我想到下面几种:
①对于初始的网络。若图的流向是一样的。那么就直接推断对于一条边k的正向边k>>1<<1是否满流。
②对于一般的,能够存流量限制。
③或者对每条边再存个tag。若tag=1,则表示初始时这条边容量限制非0,否则是0。
[Q&A]
问题1:为什么这样搜索能够出解而不错误?
回答1:这不是非常明显的嘛,因为满流了,所以除原点和汇点外的每一个节点连接且仅连接两个节点。
这样从一个节点过来。那么必定仅仅能从还有一个节点出去。
最后必定会有一个节点连接到第一个节点。这是就停止了。假如没有。那么一直找到了第n个节点就找不到了。矛盾。
特殊的,对于每一个连通集合的第一个节点,选择了随意一个相邻的节点,这也是没问题的。
[Sum]
①对于素数的问题,要想到奇偶分析。
②k!=-1。等价于~k,这里能够化简。事实上scanf("%d",&a)这个函数假设读不到不论什么东西,返回的值也是-1。
之所以能这样由于-1的二进制为最大即2^k-1,取反后为0。而其它取反都非0。
③推断满流的三种办法。
④回想了网络流算法。
[Code]
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std; const int N=240;
const int M=N*N;
const int P=20001; int n,odd[N],even[N];
int w[N],pri[P],vp[P];
struct G
{
int v,f,nxt;
}map[M+M];
int tt,hd[N];
int level[N],q[N],h,t;
G list[N]; int tl,used[N],fs[N],num,cnt[N]; inline int read(void)
{
int s=0; char c=getchar();
for (;c<'0'||c>'9';c=getchar());
for (;'0'<=c&&c<='9';c=getchar()) s=s*10+c-'0';
return s;
} inline void ins(int u,int v,int f)
{
map[++tt].v=v;
map[tt].f=f;
map[tt].nxt=hd[u];
hd[u]=tt;
} int init(void)
{
n=read(); for (int i=1;i<=n;i++)
{
w[i]=read();
if (w[i]&1)
odd[++odd[0]]=i;
else even[++even[0]]=i;
}
if (odd[0]^even[0]) return 0; for (int i=2;i<P;i++)
{
if (!vp[i]) pri[++pri[0]]=i;
for (int j=1;j<=pri[0];j++)
{
if (i*pri[j]>=P) break;
vp[i*pri[j]]=1;
if (i%pri[j]==0) break;
}
} tt=-1; memset(hd,-1,sizeof hd);
for (int i=1;i<=odd[0];i++)
{
ins(0,odd[i],2),ins(odd[i],0,0);
for (int j=1;j<=even[0];j++)
if (!vp[w[odd[i]]+w[even[j]]])
ins(odd[i],even[j],1),ins(even[j],odd[i],0);
}
for (int i=1;i<=even[0];i++)
ins(even[i],n+1,2),ins(n+1,even[i],0); return 1;
} int BFS(void)
{
memset(level,-1,sizeof level);
h=0,t=1,q[t]=0,level[0]=0; int k;
for (;h^t;)
{
k=q[++h];
for (int r=hd[k];~r;r=map[r].nxt)
if (map[r].f&&level[map[r].v]==-1)
{
level[map[r].v]=level[k]+1;
if (map[r].v==n+1) return 1;
q[++t]=map[r].v;
}
}
return 0;
} inline int min(int i,int j)
{
return i<j?i:j;
} int DFS(int now,int flow)
{
if (now==n+1) return flow;
int sum=0,tmp;
for (int k=hd[now];~k;k=map[k].nxt)
if (map[k].f&&level[now]+1==level[map[k].v])
{
tmp=DFS(map[k].v,min(flow,map[k].f));
if (tmp)
{
map[k].f-=tmp;
map[k^1].f+=tmp;
flow-=tmp;
sum+=tmp;
if (!flow) break;
}
else level[map[k].v]=P;
}
return sum;
} inline void inslist(int now)
{
list[++tl].v=now;
list[tl].nxt=fs[num];
fs[num]=tl;
} void dfs(int now,int fst)
{
cnt[num]++;
used[now]=1;
inslist(now); for (int k=hd[now];k;k=map[k].nxt)
if (!map[k>>1<<1].f&&map[k].v&&map[k].v^n+1)
{
if (fst==map[k].v) return;
if (!used[map[k].v]) dfs(map[k].v,fst);
}
} int work(void)
{
int sum=0;
for (;BFS();) sum+=DFS(0,P);
if (sum^n) return 0; for (int i=1;i<=n;i++)
if (!used[i])
{
num++;
dfs(i,i);
} printf("%d\n",num);
for (int i=1;i<=num;i++)
{
printf("%d ",cnt[i]);
for (int j=fs[i];j;j=list[j].nxt)
printf("%d ",list[j].v);
printf("\n");
} return 1;
} int main(void)
{
int d=init();
if (d) d=work();
if (!d) printf("Impossible\n"); return 0;
}
【Codeforces】512C Fox and Dinner的更多相关文章
- 【Codeforces】Round #491 (Div. 2) 总结
[Codeforces]Round #491 (Div. 2) 总结 这次尴尬了,D题fst,E没有做出来.... 不过还好,rating只掉了30,总体来说比较不稳,下次加油 A:If at fir ...
- 【Codeforces】Round #488 (Div. 2) 总结
[Codeforces]Round #488 (Div. 2) 总结 比较僵硬的一场,还是手速不够,但是作为正式成为竞赛生的第一场比赛还是比较圆满的,起码没有FST,A掉ABCD,总排82,怒涨rat ...
- 【CodeForces】601 D. Acyclic Organic Compounds
[题目]D. Acyclic Organic Compounds [题意]给定一棵带点权树,每个点有一个字符,定义一个结点的字符串数为往下延伸能得到的不重复字符串数,求min(点权+字符串数),n&l ...
- 【Codeforces】849D. Rooter's Song
[算法]模拟 [题意]http://codeforces.com/contest/849/problem/D 给定n个点从x轴或y轴的位置p时间t出发,相遇后按对方路径走,问每个数字撞到墙的位置.(还 ...
- 【CodeForces】983 E. NN country 树上倍增+二维数点
[题目]E. NN country [题意]给定n个点的树和m条链,q次询问一条链(a,b)最少被多少条给定的链覆盖.\(n,m,q \leq 2*10^5\). [算法]树上倍增+二维数点(树状数组 ...
- 【CodeForces】925 C.Big Secret 异或
[题目]C.Big Secret [题意]给定数组b,求重排列b数组使其前缀异或和数组a单调递增.\(n \leq 10^5,1 \leq b_i \leq 2^{60}\). [算法]异或 为了拆位 ...
- 【CodeForces】700 D. Huffman Coding on Segment 哈夫曼树+莫队+分块
[题目]D. Huffman Coding on Segment [题意]给定n个数字,m次询问区间[l,r]的数字的哈夫曼编码总长.1<=n,m,ai<=10^5. [算法]哈夫曼树+莫 ...
- 【CodeForces】906 D. Power Tower 扩展欧拉定理
[题目]D. Power Tower [题意]给定长度为n的正整数序列和模数m,q次询问区间[l,r]累乘幂%m的答案.n,q<=10^5,m,ai<=10^9. [算法]扩展欧拉定理 [ ...
- 【CodeForces】741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
[题意]给定n个点的树,每条边有一个小写字母a~v,求每棵子树内的最长回文路径,回文路径定义为路径上所有字母存在一种排列为回文串.n<=5*10^5. [算法]dsu on tree [题解]这 ...
随机推荐
- CVX安装使用
CVX下载 下载地址 使用手册 Using Gurobi with CVX Using MOSEK with CVX CVX安装 下载压缩文件后解压缩至任意地址,打开matlab,进入解压缩后的地址, ...
- oracle数据库安装教程以及问题和解决方法
一,oracle数据库的下载和安装 1,在oracle官网上下载oracle安装包,运行setup.exe. 2,点击取消“我希望同构My Oracle Support接受安全更新”,以防后患. 3, ...
- hdu5389(DP)
题意: 给出n个人的id,有两个门,每一个门有一个标号.我们记作a和b,如今我们要将n个人分成两组,进入两个门中,使得两部分人的标号的和(迭代的求,直至变成一位数.我们姑且叫做求"和&quo ...
- poj2385(dp)
题目链接:http://poj.org/problem?id=2385 Apple Catching Time Limit: 1000MS Memory Limit: 65536K Total S ...
- android选择图片或拍照图片上传到server(包含上传參数)
在9ria论坛看到的.还没測试,先Mark与大家分享一下. 近期要搞一个项目,须要上传相冊和拍照的图片.不负所望,最终完毕了! 只是须要说明一下,事实上网上非常多教程拍照的图片.都是缩略图不是非常清晰 ...
- 51nod-1253: Kundu and Tree
[传送门:51nod-1253] 简要题意: 给出一棵n个点的树,树上的边要么为黑,要么为红 求出所有的三元组(a,b,c)的数量,满足a到b,b到c,c到a三条路径上分别有至少一条红边 题解: 显然 ...
- nyoj--55--懒省事的小明(STL优先队列)
懒省事的小明 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分 ...
- BZOJ 2096 单调队列
思路: 偷懒用的STL //By SiriusRen #include <deque> #include <cstdio> using namespace std; struc ...
- P2742 [USACO5.1]圈奶牛Fencing the Cows
题目描述 农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏.他建造的围栏必须包括他的奶牛喜欢吃草的所有地点.对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度. 输入输出格式 输入 ...
- Codeforces 987C. Three displays(o(n^2))
刚开始三重循环tle test11.后来想了个双重循环的方法. 解题思路: 1.双重循环一次,用一个一位数组存j和比j小的i的和的最小值. 2.再双重循环一次,找到比j大的数k,更新结果为ans=mi ...