bzoj 5120 无限之环 & 洛谷 P4003 —— 费用流(多路增广SPFA)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5120
https://www.luogu.org/problemnew/show/P4003
神奇的费用流建图;
首先,网格图,相邻之间有关系,所以先二分染色一下;
然后发现问题就是染色后黑白点之间要完美匹配插头;
所以可以考虑把旋转通过带一些代价变成插头方向的变化;
把一个格子拆成上下左右四个点,分类讨论,连边即可;
然而一开始连边竟然写了100多行...然后T了;
看了看题解代码,突然悟到了一些压行的方式,于是把建图压成了40行;
但还是T了,于是又改来改去,还把题解的建图粘过来囧,然后WA了;
这250行左右的代码就是一下午的辛酸调试:
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- using namespace std;
- int const xn=1e5,xm=4e5,inf=1e9;//
- int n,m,hd[xn],ct=,to[xm],nxt[xm],w[xn],c[xn];
- int dis[xn],pre[xn],inc[xn],S,T;
- bool vis[xn];
- queue<int>q;
- int rd()
- {
- int ret=,f=; char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
- while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
- return f?ret:-ret;
- }
- int Min(int x,int y){return x<y?x:y;}
- void ade(int x,int y,int z,int f){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct; w[ct]=z; c[ct]=f;}
- void add(int x,int y,int z,int f){ade(x,y,z,f); ade(y,x,-z,);}
- int d[],bin[];
- int id(int x,int y,int k){return ((x-)*m+y-)*+k;}
- inline int get(int x)
- {
- int ret=;
- for(int i=;i<=;i++)
- if(x&bin[i-])d[i]=,ret++; else d[i]=;
- return ret;
- }
- inline int op(int x){if(x<=)return x+; return x-;}
- inline bool ck(){return (d[]&&d[]&&!d[]&&!d[])||(d[]&&d[]&&!d[]&&!d[]);}
- inline bool bfs()
- {
- for(int i=S;i<=T;i++)vis[i]=;
- for(int i=S;i<=T;i++)dis[i]=inf;
- dis[S]=; inc[S]=inf; vis[S]=; q.push(S);
- while(q.size())
- {
- int x=q.front(); q.pop(); vis[x]=;
- //printf("x=%d d=%d\n",x,dis[x]);
- for(int i=hd[x],u;i;i=nxt[i])
- if(dis[u=to[i]]>dis[x]+w[i]&&c[i])
- {
- //if(w[i]<0)printf("i=%d w=%d c=%d\n",i,w[i],c[i]);
- dis[u]=dis[x]+w[i]; pre[u]=i;
- inc[u]=Min(inc[x],c[i]);
- if(!vis[u])vis[u]=,q.push(u);
- }
- }
- //printf("dis[%d]=%d\n",T,dis[T]);
- return dis[T]!=inf;
- }
- inline void up()
- {
- int x=T;
- while(x!=S)
- {
- int i=pre[x];
- c[i]-=inc[T]; c[i^]+=inc[T];
- x=to[i^];
- }
- }
- int main()
- {
- n=rd(); m=rd(); S=; T=n*m*+;
- bin[]=; for(int i=;i<=;i++)bin[i]=(bin[i-]<<);
- int goal=;
- for (int i=;i<=n;i++)
- for (int j=;j<=m;j++)
- {
- int x=rd(),u=; int t=(((i+j)&)==);
- for (int k=;k<=;k++)
- {
- int nw=id(i,j,k);
- if (x&(<<(k-))) u++,t?add(S,nw,,):add(nw,T,,);
- }
- goal+=u;
- if (x==||x==) continue;
- if (u==||u==) for (int k=;k<=;k++) add(id(i,j,k),id(i,j,k+&),,),add(id(i,j,k+&),id(i,j,k),,);
- if (u==)
- {
- add(id(i,j,),id(i,j,),,),add(id(i,j,),id(i,j,),,);
- add(id(i,j,),id(i,j,),,),add(id(i,j,),id(i,j,),,);
- }
- }
- if (goal&) {puts("-1");return ;}goal>>=;
- for (int i=;i<=n;i++)
- for (int j=;j<=m;j++)
- if (((i+j)&)==)
- {
- if (i>) add(id(i,j,),id(i-,j,),,);
- if (j<m) add(id(i,j,),id(i,j+,),,);
- if (i<n) add(id(i,j,),id(i+,j,),,);
- if (j>) add(id(i,j,),id(i,j-,),,);
- }
- /*
- for(int i=1;i<=n;i++)
- for(int j=1;j<=m;j++)
- {
- int x=rd(); int cnt=get(x); goal+=cnt;
- bool t=(((i+j)&1)==0);
- if(t){for(int k=1;k<=4;k++)if(d[k])add(S,id(i,j,k),0,1);}
- else {for(int k=1;k<=4;k++)if(d[k])add(id(i,j,k),T,0,1);}
- if(x==5||x==10)continue;
- if(cnt==1)
- {
- int nw; for(int k=1;k<=4;k++)if(d[k]){nw=k; break;}
- if(t){for(int k=1;k<=4;k++)if(!d[k])add(nw,id(i,j,k),(k==op(nw)?2:1),1);}
- else {for(int k=1;k<=4;k++)if(!d[k])add(id(i,j,k),nw,(k==op(nw)?2:1),1);}
- }
- if(cnt==3)
- {
- int nw; for(int k=1;k<=4;k++)if(!d[k]){nw=k; break;}
- if(t){for(int k=1;k<=4;k++)if(d[k])add(id(i,j,k),nw,(k==op(nw)?2:1),1);}
- else {for(int k=1;k<=4;k++)if(d[k])add(nw,id(i,j,k),(k==op(nw)?2:1),1);}
- }
- if(cnt==2)
- {
- if(t){for(int k=1;k<=4;k++)if(d[k])add(id(i,j,k),id(i,j,op(k)),1,1);}
- else {for(int k=1;k<=4;k++)if(d[k])add(id(i,j,op(k)),id(i,j,k),1,1);}
- }
- }
- for(int i=1;i<=n;i++)
- for(int j=1;j<=m;j++)
- if(((i+j)&1)==0)
- {
- if(i>1)add(id(i,j,1),id(i-1,j,3),0,1);
- if(j<m)add(id(i,j,2),id(i,j+1,4),0,1);
- if(i<n)add(id(i,j,3),id(i+1,j,1),0,1);
- if(j>1)add(id(i,j,4),id(i,j-1,2),0,1);
- }
- */
- /*
- if(((i+j)&1)==0)//black
- {
- if(!ck())//!straight
- {
- if(cnt==1)
- {
- for(int k=1;k<=4;k++)
- if(d[k])
- {
- int nw=id(i,j,k); add(S,nw,0,1);
- for(int l=1;l<=4;l++)
- if(l==k)continue;
- else if(l==op(k))add(nw,id(i,j,l),2,1);
- else add(nw,id(i,j,l),1,1);
- break;
- }
- }
- else if(cnt==2)
- {
- for(int k=1;k<=4;k++)
- if(d[k])
- {
- add(S,id(i,j,k),0,1);
- add(id(i,j,k),id(i,j,op(k)),1,1);
- }
- }
- else if(cnt==3)
- {
- for(int k=1;k<=4;k++)
- if(d[k])add(S,id(i,j,k),0,1);
- else
- {
- for(int l=1,nw=id(i,j,k);l<=4;l++)
- if(l==k)continue;
- else if(l==op(k))add(id(i,j,l),nw,2,1);
- else add(id(i,j,l),nw,1,1);
- }
- }
- else if(cnt==4)
- for(int k=1;k<=4;k++)add(S,id(i,j,k),0,1);
- if(i-1)add(id(i,j,1),id(i-1,j,3),0,1);
- if(j<m)add(id(i,j,2),id(i,j+1,4),0,1);
- if(i<n)add(id(i,j,3),id(i+1,j,1),0,1);
- if(j-1)add(id(i,j,4),id(i,j-1,2),0,1);
- }
- else//straight
- {
- for(int k=1;k<=4;k++)
- if(d[k])add(S,id(i,j,k),0,1);
- if(i-1&&d[1])add(id(i,j,1),id(i-1,j,3),0,1);
- if(j<m&&d[2])add(id(i,j,2),id(i,j+1,4),0,1);
- if(i<n&&d[3])add(id(i,j,3),id(i+1,j,1),0,1);
- if(j-1&&d[4])add(id(i,j,4),id(i,j-1,2),0,1);
- }
- }
- else//white
- {
- if(!ck())//!straight
- {
- if(cnt==1)
- {
- for(int k=1;k<=4;k++)
- if(d[k])
- {
- int nw=id(i,j,k); add(nw,T,0,1);
- for(int l=1;l<=4;l++)
- if(l==k)continue;
- else if(l==op(k))add(id(i,j,l),nw,2,1);
- else add(id(i,j,l),nw,1,1);
- break;
- }
- }
- else if(cnt==2)
- {
- for(int k=1;k<=4;k++)
- if(d[k])
- {
- add(id(i,j,k),T,0,1);
- add(id(i,j,op(k)),id(i,j,k),1,1);
- }
- }
- else if(cnt==3)
- {
- for(int k=1;k<=4;k++)
- if(d[k])add(id(i,j,k),T,0,1);
- else
- {
- int nw=id(i,j,k);
- for(int l=1;l<=4;l++)
- if(l==k)continue;
- else if(l==op(k))add(nw,id(i,j,l),2,1);
- else add(nw,id(i,j,l),1,1);
- }
- }
- else if(cnt==4)
- for(int k=1;k<=4;k++)add(id(i,j,k),T,0,1);
- }
- else//straight
- {
- for(int k=1;k<=4;k++)
- if(d[k])add(id(i,j,k),T,0,1);
- }
- }
- }
- */
- //if(goal&1){puts("-1"); return 0;} goal>>=1;
- int ans=,flow=;
- while(bfs())ans+=dis[T]*inc[T],flow+=inc[T],up();
- if(flow==goal)printf("%d\n",ans);
- else puts("-1");
- return ;
- }
囧
突然发现连边里 nw 和 id(i,j,nw) 不分了,改过来后竟然——就A了!
但是空间必须开 4e5?明明我一开始算的应该是 4e4 ...
然而这篇代码在洛谷上一交,全是TLE...似乎还应该写多路增广SPFA...
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- using namespace std;
- int const xn=1e5,xm=4e5,inf=1e9;
- int n,m,hd[xn],ct=,to[xm],nxt[xm],w[xn],c[xn];
- int dis[xn],pre[xn],inc[xn],S,T;
- bool vis[xn];
- queue<int>q;
- int rd()
- {
- int ret=,f=; char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
- while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
- return f?ret:-ret;
- }
- int Min(int x,int y){return x<y?x:y;}
- void ade(int x,int y,int z,int f){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct; w[ct]=z; c[ct]=f;}
- void add(int x,int y,int z,int f){ade(x,y,z,f); ade(y,x,-z,);}
- int d[],bin[];
- int id(int x,int y,int k){return ((x-)*m+y-)*+k;}
- inline int get(int x)
- {
- int ret=;
- for(int i=;i<=;i++)
- if(x&bin[i-])d[i]=,ret++; else d[i]=;
- return ret;
- }
- inline int op(int x){if(x<=)return x+; return x-;}
- inline bool ck(){return (d[]&&d[]&&!d[]&&!d[])||(d[]&&d[]&&!d[]&&!d[]);}
- inline bool bfs()
- {
- for(int i=S;i<=T;i++)dis[i]=inf;
- dis[S]=; inc[S]=inf; vis[S]=; q.push(S);
- while(q.size())
- {
- int x=q.front(); q.pop(); vis[x]=;
- for(int i=hd[x],u;i;i=nxt[i])
- if(dis[u=to[i]]>dis[x]+w[i]&&c[i])
- {
- dis[u]=dis[x]+w[i]; pre[u]=i;
- inc[u]=Min(inc[x],c[i]);
- if(!vis[u])vis[u]=,q.push(u);
- }
- }
- return dis[T]!=inf;
- }
- inline void up()
- {
- int x=T;
- while(x!=S)
- {
- int i=pre[x];
- c[i]-=inc[T]; c[i^]+=inc[T];
- x=to[i^];
- }
- }
- int main()
- {
- n=rd(); m=rd(); S=; T=n*m*+;
- bin[]=; for(int i=;i<=;i++)bin[i]=(bin[i-]<<);
- int goal=;
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- {
- int x=rd(); int cnt=get(x); goal+=cnt;
- bool t=(((i+j)&)==);
- if(t){for(int k=;k<=;k++)if(d[k])add(S,id(i,j,k),,);}
- else {for(int k=;k<=;k++)if(d[k])add(id(i,j,k),T,,);}
- if(x==||x==)continue;
- if(cnt==)
- {
- int nw; for(int k=;k<=;k++)if(d[k]){nw=k; break;}
- if(t){for(int k=;k<=;k++)if(!d[k])add(id(i,j,nw),id(i,j,k),(k==op(nw)?:),);}//id(i,j,nw)!!
- else {for(int k=;k<=;k++)if(!d[k])add(id(i,j,k),id(i,j,nw),(k==op(nw)?:),);}
- }
- if(cnt==)
- {
- int nw; for(int k=;k<=;k++)if(!d[k]){nw=k; break;}
- if(t){for(int k=;k<=;k++)if(d[k])add(id(i,j,k),id(i,j,nw),(k==op(nw)?:),);}
- else {for(int k=;k<=;k++)if(d[k])add(id(i,j,nw),id(i,j,k),(k==op(nw)?:),);}
- }
- if(cnt==)
- {
- if(t){for(int k=;k<=;k++)if(d[k])add(id(i,j,k),id(i,j,op(k)),,);}
- else {for(int k=;k<=;k++)if(d[k])add(id(i,j,op(k)),id(i,j,k),,);}
- }
- }
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- if(((i+j)&)==)
- {
- if(i>)add(id(i,j,),id(i-,j,),,);
- if(j<m)add(id(i,j,),id(i,j+,),,);
- if(i<n)add(id(i,j,),id(i+,j,),,);
- if(j>)add(id(i,j,),id(i,j-,),,);
- }
- if(goal&){puts("-1"); return ;} goal>>=;
- int ans=,flow=;
- while(bfs())ans+=dis[T]*inc[T],flow+=inc[T],up();
- if(flow==goal)printf("%d\n",ans);
- else puts("-1");
- return ;
- }
单路增广SPFA
于是学习了一下多路增广SPFA的写法,似乎就是用SPFA跑出一些可行路线,然后 dinic,据说在边多流量少的图上作用很好;
竟然一下子跑得飞快,吓了一跳!这时间根本不是一个层次的啊!实在是妙!
代码如下:
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- using namespace std;
- int const xn=1e5,xm=4e5,inf=1e9;
- int n,m,hd[xn],ct=,to[xm],nxt[xm],w[xn],c[xn];
- int dis[xn],pre[xn],S,T,cur[xn],ans;
- bool vis[xn];
- queue<int>q;
- int rd()
- {
- int ret=,f=; char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
- while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
- return f?ret:-ret;
- }
- int Min(int x,int y){return x<y?x:y;}
- void ade(int x,int y,int z,int f){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct; w[ct]=z; c[ct]=f;}
- void add(int x,int y,int z,int f){ade(x,y,z,f); ade(y,x,-z,);}
- int d[],bin[];
- int id(int x,int y,int k){return ((x-)*m+y-)*+k;}
- inline int get(int x)
- {
- int ret=;
- for(int i=;i<=;i++)
- if(x&bin[i-])d[i]=,ret++; else d[i]=;
- return ret;
- }
- inline int op(int x){if(x<=)return x+; return x-;}
- inline bool ck(){return (d[]&&d[]&&!d[]&&!d[])||(d[]&&d[]&&!d[]&&!d[]);}
- bool SPFA()
- {
- for(int i=S;i<=T;i++)vis[i]=;
- for(int i=S;i<=T;i++)dis[i]=inf;
- dis[S]=, q.push(S);
- while(q.size())
- {
- int x=q.front(); q.pop(), vis[x]=;
- for(int i=hd[x],u;i;i=nxt[i])
- if(dis[u=to[i]]>dis[x]+w[i]&&c[i])
- {
- dis[u]=dis[x]+w[i];
- if(!vis[u])vis[u]=,q.push(u);
- }
- }
- return dis[T]!=inf;
- }
- int dfs(int x,int fl)
- {
- if(x==T)return fl;
- vis[x]=;
- for(int &i=cur[x],u,tmp;i;i=nxt[i])
- if(!vis[u=to[i]]&&c[i]&&dis[u]==dis[x]+w[i])
- if(tmp=dfs(u,Min(fl,c[i])))
- {c[i]-=tmp,c[i^]+=tmp,ans+=w[i]*tmp; return tmp;}
- return ;
- }
- int MCMF()
- {
- int ret=;
- while(SPFA())
- {
- for(int i=S;i<=T;i++)cur[i]=hd[i];
- int tmp;
- while(tmp=dfs(S,inf))ret+=tmp;
- }
- return ret;
- }
- int main()
- {
- n=rd(); m=rd(); S=; T=n*m*+;
- bin[]=; for(int i=;i<=;i++)bin[i]=(bin[i-]<<);
- int goal=;
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- {
- int x=rd(); int cnt=get(x); goal+=cnt;
- bool t=(((i+j)&)==);
- if(t){for(int k=;k<=;k++)if(d[k])add(S,id(i,j,k),,);}
- else {for(int k=;k<=;k++)if(d[k])add(id(i,j,k),T,,);}
- if(x==||x==)continue;
- if(cnt==)
- {
- int nw; for(int k=;k<=;k++)if(d[k]){nw=k; break;}
- if(t){for(int k=;k<=;k++)if(!d[k])add(id(i,j,nw),id(i,j,k),(k==op(nw)?:),);}//id(i,j,nw)!!
- else {for(int k=;k<=;k++)if(!d[k])add(id(i,j,k),id(i,j,nw),(k==op(nw)?:),);}
- }
- if(cnt==)
- {
- int nw; for(int k=;k<=;k++)if(!d[k]){nw=k; break;}
- if(t){for(int k=;k<=;k++)if(d[k])add(id(i,j,k),id(i,j,nw),(k==op(nw)?:),);}
- else {for(int k=;k<=;k++)if(d[k])add(id(i,j,nw),id(i,j,k),(k==op(nw)?:),);}
- }
- if(cnt==)
- {
- if(t){for(int k=;k<=;k++)if(d[k])add(id(i,j,k),id(i,j,op(k)),,);}
- else {for(int k=;k<=;k++)if(d[k])add(id(i,j,op(k)),id(i,j,k),,);}
- }
- }
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- if(((i+j)&)==)
- {
- if(i>)add(id(i,j,),id(i-,j,),,);
- if(j<m)add(id(i,j,),id(i,j+,),,);
- if(i<n)add(id(i,j,),id(i+,j,),,);
- if(j>)add(id(i,j,),id(i,j-,),,);
- }
- if(goal&){puts("-1"); return ;} goal>>=;
- int flow=MCMF();
- if(flow==goal)printf("%d\n",ans);
- else puts("-1");
- return ;
- }
bzoj 5120 无限之环 & 洛谷 P4003 —— 费用流(多路增广SPFA)的更多相关文章
- 落谷p3376 最大流EdmondsKarp增广路模板
参考: https://blog.csdn.net/txl199106/article/details/64441994 分析: 该算法是用bfs求出是否有路从s到t, 然后建立反向边(关于反向边), ...
- 草地排水 洛谷P2740 最大流 入门题目
草地排水 洛谷P2740 最大流入门题目 题意 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一 ...
- LOJ 2979 「THUSCH 2017」换桌——多路增广费用流
题目:https://loj.ac/problem/2979 原来的思路: 优化连边.一看就是同一个桌子相邻座位之间连边.相邻桌子对应座位之间连边. 每个座位向它所属的桌子连边.然后每个人建一个点,向 ...
- 洛谷P4003 无限之环(infinityloop)(网络流,费用流)
洛谷题目传送门 题目 题目描述 曾经有一款流行的游戏,叫做 Infinity Loop,先来简单的介绍一下这个游戏: 游戏在一个 n ∗ m 的网格状棋盘上进行,其中有些小方格中会有水管,水管可能在格 ...
- 洛谷P4003 无限之环(费用流)
传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...
- 洛谷P4003 [国家集训队2017]无限之环 网络流 最小费用最大流
题意简述 有一个\(n\times m\)棋盘,棋盘上每个格子上有一个水管.水管共有\(16\)种,用一个\(4\)位二进制数来表示当前水管向上.右.下.左有个接口.你可以旋转除了\((0101)_2 ...
- LOJ 2321 清华集训2017 无限之环 拆点+最小费用最大流
题面:中文题面,这里不占用篇幅 分析: 看到题面,我就想弃疗…… 但是作为任务题单,还是抄了题解…… 大概就是将每个格子拆点,拆成五个点,上下左右的触点和一个负责连源汇点的点(以下简称本点). 这个这 ...
- 【题解】洛谷P1073 [NOIP2009TG] 最优贸易(SPFA+分层图)
次元传送门:洛谷P1073 思路 一开始看题目嗅出了强连通分量的气息 但是嫌长没打 听机房做过的dalao说可以用分层图 从来没用过 就参考题解了解一下 因为每个城市可以走好几次 所以说我们可以在图上 ...
- 洛谷P1462 通往奥格瑞玛的道路(二分+spfa,二分+Dijkstra)
洛谷P1462 通往奥格瑞玛的道路 二分费用. 用血量花费建图,用单源最短路判断 \(1\) 到 \(n\) 的最短路花费是否小于 \(b\) .二分时需要不断记录合法的 \(mid\) 值. 这里建 ...
随机推荐
- PAT 1062. 最简分数(20)
一个分数一般写成两个整数相除的形式:N/M,其中M不为0.最简分数是指分子和分母没有公约数的分数表示形式. 现给定两个不相等的正分数 N1/M1 和 N2/M2,要求你按从小到大的顺序列出它们之间分母 ...
- centos7 运行postgres 数据库脚本db.sql
[root@localhost ~]# su postgresbash-4.2$ psqlcould not change directory to "/root": Permis ...
- python3 生成随即激活码
import string import random #激活码中的字符和数字 field = string.ascii_letters + string.digits #获得四个字母和数字的随即组合 ...
- 基于CocoaPods的iOS项目模块化实践
什么是CocoaPods? CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has ove ...
- 第七篇、os、sys、random、time、datetime、logging
一.sys 用于提供对Python解释器相关的操作: 1 2 3 4 5 6 7 8 9 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) ...
- python内置方法补充bin
bin(x) 英文说明:Convert an integer number to a binary string. The result is a valid Python expression. I ...
- matlab函数之imresize()
B = imresize(A,scale) B = imresize(A,scale) 返回图像 B,它是将 A 的长宽大小缩放 scale 倍之后的图像.输入图像 A 可以是灰度.RGB 或二值图像 ...
- css3 多列布局使用
css3的出现,解决了不少前端的问题,比如动画,圆角等: 这里总结一下css3 的多列布局: w3c上给出了很多属性: 我们一般用到column-count.column-gap.column-wid ...
- Spring MVC工作原理(好用版)
Spring MVC工作原理 参考: SpringMVC工作原理 - 平凡希 - 博客园https://www.cnblogs.com/xiaoxi/p/6164383.html SpringMVC的 ...
- java:类集回顾
1.类集设置的主要目的:动态的对象数组 2.类集中有以下几个接口: Collection:是存放单值的最大父接口 |- List接口:里面的内容是允许重复的 |- ArrayList, Vector, ...