【JZOJ5537】【2014东莞市选】分组(网络流)
2018-01-22 21:56
211 查看
Problem
有n个字符串,给这些字符串分组,使得每个字符串属于且仅属于一个组。对于一个合法的分组,至少满足以下两个条件种的一个:
1. 所有字符串的k前缀相同(即前k个字母相同)
2. 所有字符串的k后缀相同(即后k个字母相同)
你需要给这些字符串分组,使得所分的组数最少。
Input
第一行两个整数n,k(1<=n<=5000, 1<=k<=550),分别表示字符串的数量以及题述中的参数k。接下来有n行,每行一个字符串,字符串的长度至少为k,且不会超过550。
Output
第一行一个整数m,表示最少的分组数目。接下来m行,每行的第一个整数ti表示第i个分组的字符串数量,接下来有ti个整数,表示第i个分组中的字符串编号,编号对应字符串的输入顺序。数字之间用一个空格隔开。如果分组方案不唯一,输出任意一种即可。
Solution
这道题我刚看完后觉得不太可做。首先,考虑将所有字符串的前缀、后缀离散化。首先想到trie,但是空间复杂度为O(nk∗26),极限数据可达到O(71500000),显然会炸。然后想到快排离散。至于哈希,虽然时间复杂度可以去掉一个log,但却有匹配错误的概率。
然后考虑转换模型。可以发现,如果将前、后缀视作节点,将每个字符串视作连接其前、后缀的边,那便是一个二分图。我们可以从超级源(S)向每个前缀各建1条流量为1的边,从每个字符串的前缀向后缀建1条流量为无穷大的边,从每个后缀向超级汇(T)均建1条流量为1的边。这样建边保证我们后面求最小割时不会割到字符串。
那么我们从超级源流一遍最大流。我们知道流完一遍后,某些边会变成反向弧,这样就使得原图变成了两个分别包括S、T但互不相连的点集。我们设其为点集{S}和点集{T}。
这样的话,如何求出最小割割集呢?我想了很久,最后问了lyl并得到启发:我们在流完之后,从S做一遍flood fill,标记出所有可从超级源到达的节点,则这些点全部属于{S}。若某个前缀可从S到达,那么说明此前缀属于{S},因此S到其的边定然不是割边;若某个后缀可从S到达,那么说明此后缀不属于{T},因此其到T的边定然是割边。
那么,我们必须选择那些被割的点,因为我们求出的是最小割,所以可以保证m最小。而对于每个字符串,我们随便选择它连接的一个被割的点即可。
而此图的点数、边数最坏情况是2n,所以此题时间复杂度的理论上限是O(n3)。但是我们使用SAP,加上邻接表优化、GAP优化、当前弧优化,再加上网络流的时间复杂度向来玄学地快,所以我才跑了277ms。
时间复杂度:O(玄)。
Code
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define N 5010 #define K 560 #define fo(i,a,b) for(i=a;i<=b;i++) #define fs(i,x) for(it=x;it;it=ne[it]) int i,j,l,n,k,len,cnt,pr ,to ,ps,dis[2*N],vh[2*N],m,sum,tot,ty[100*N],tl[100*N],ne[100*N],la[2*N],di[2*N],il; char s[K]; bool p[2*N],bz ; struct S { char s[K]; int num; }pre ,tov ; struct X { int it,x; }last[2*N]; bool operator<(const S&a,const S&b) { int i; fo(i,0,k-1) if(a.s[i]<b.s[i])return 1; else if(a.s[i]>b.s[i])return 0; return 0; } void insert(int x,int y,int len) { ty[++tot]=y; tl[tot]=len; ne[tot]=la[x]; la[x]=tot; } void sap() { int i,j,aug,mi,it,x; vh[0]=cnt+2; fo(i,0,cnt)di[i]=la[i]; i=0; bool flag; aug=1<<30; while(dis[0]<cnt+2) { flag=0; fs(i,di[i]) if(dis[j=ty[it]]+1==dis[i]&&(x=tl[it])) { flag=1; di[i]=it; aug=min(aug,x); last[j]=(X){it,i}; i=j; if(i==2*N-1) { while(i) { j=last[i].x; tl[last[i].it]-=aug; insert(i,j,aug); i=j; } aug=1<<30; } break; } if(flag)continue; mi=cnt+1; fs(i,la[i]) if(dis[ty[it]]<mi&&tl[it]) il=it,mi=dis[ty[it]]; di[i]=il; if(!--vh[dis[i]])break; dis[i]=mi+1; vh[dis[i]]++; if(i)i=last[i].x; } } void dfs(int x) { p[x]=1; int y,it; fs(x,la[x]) if(!p[y=ty[it]]&&tl[it]) dfs(y); } int main() { freopen("group.in","r",stdin); freopen("group.out","w",stdout); scanf("%d%d",&n,&k); fo(i,1,n) { scanf("%s",&s); len=strlen(s); fo(j,0,k-1) { pre[i].s[j]=s[j]; tov[i].s[j]=s[len-k+j]; } pre[i].num=tov[i].num=i; } sort(pre+1,pre+n+1); fo(i,1,n) { insert(0,++cnt,1); fo(j,i,n) { pr[pre[j].num]=cnt; if(j==n||pre[i]<pre[j+1])break; } i=j; } ps=cnt; sort(tov+1,tov+n+1); fo(i,1,n) { insert(++cnt,2*N-1,1); fo(j,i,n) { to[tov[j].num]=cnt; if(j==n||tov[i]<tov[j+1])break; } i=j; } fo(i,1,n)insert(pr[i],to[i],1<<30); sap(); dfs(0); fo(i,1,ps)m+=!p[i]; fo(i,i,cnt)m+=p[i]; printf("%d\n",m); cnt=0; fo(i,1,n) { cnt++; sum=0; fo(j,i,n) { if(!p[cnt])sum++; if(j==n||pre[i]<pre[j+1])break; } if(!p[cnt])printf("%d ",sum); fo(j,i,n) { if(!p[cnt])printf("%d ",pre[j].num),bz[pre[j].num]=1; if(j==n||pre[i]<pre[j+1])break; } if(!p[cnt])printf("\n"); i=j; } fo(i,1,n) { cnt++; sum=0; fo(j,i,n) { if(p[cnt]&&!bz[tov[j].num])sum++; if(j==n||tov[i]<tov[j+1])break; } if(p[cnt])printf("%d ",sum); fo(j,i,n) { if(p[cnt]&&!bz[tov[j].num])printf("%d ",tov[j].num); if(j==n||tov[i]<tov[j+1])break; } if(p[cnt])printf("\n"); i=j; } }
相关文章推荐
- JZOJ5537.【2014东莞市选】【JSOI2014】病毒分类
- jzoj5537 [2014东莞市选]分组 二分图
- 最小割求方案 & jzoj5537 【2014东莞市选】分组
- 【2014东莞市选】分组
- January 22nd 模拟赛A&B T3 【2014东莞市选】分组 Solution
- 【2014东莞市选】分组
- jzoj 5537. 【2014东莞市选】分组 最小割
- 【有上下界网络流+费用流多路增广】【bzoj 3876】: [Ahoi2014]支线剧情
- jzoj 5535. 【2014东莞市选】登机 dp
- 2014多校10(1005)hdu4975(网络流isap+判断唯一性)
- jzoj 5536. 【2014东莞市选】游戏 水题
- 可在广域网部署运行的QQ高仿版 -- GG2014 完美版!新增支持:聊天记录、好友分组、托盘闪动消息提醒、登录状态、GIF动态表情
- bzoj3504: [Cqoi2014]危桥 网络流
- 【网络流】BZOJ 3876 [Ahoi2014]支线剧情
- BZOJ-3876-支线剧情-Ahoi2014-上下界网络流
- JZOJsenior5536.【2014东莞市选】游戏
- BZOJ 3504: [Cqoi2014]危桥|网络流
- hdu4940Destroy Transportation system【无源汇点有上下流限制的网络流】2014多校联合
- hdu 4888 2014多校第三场1002 Redraw Beautiful Drawings 网络流
- 【NOIP2014八校联考第2场第2试9.28】分组(group)