JZOJ 5404. 【NOIP2017提高A组模拟10.10】Graph
2017-10-12 20:39
579 查看
题目
给定一张n个点m条边的无向图,每条边连接两个顶点,保证无重边自环,不保证连通你想在这张图上进行若干次旅游,每次旅游可以任选一个点x作为起点,再走到一个与x 直接有边相连的点y,再走到一个与y 直接有边相连的点z 并结束本次旅游
作为一个旅游爱好者,你不希望经过任意一条边超过一次,注意一条边不能即正向走一次又反向走一次,注意点可以经过多次,在满足此条件下,你希望进行尽可能多次的旅游,请计算出最多能进行的旅游次数并输出任意一种方案。
题解
我们很容易就发现,一个点数为k的连通块,它的最大旅游次数一定为⌊k−12⌋,因为我们只两两匹配边,点可以重复选。问题难在怎么构造。
从根节点往叶节点构造是很难的, 所以我们从下往上构造。
因为先匹配深度大,再匹配深度小的点,就能保证深度大的一定能被匹配,深度小的以后可以再匹配。
反之如果先匹配深度小,再匹配深度大的点,那么深度小的不知道它所连的下面的情况处理好没有。举例:如图,按照先匹配深度小的法则我一定会匹配1,2号边,但是3,4号边没得被匹配。
所以这样得不到理论上的最大值。
具体做法:先将儿子的边两两匹配,匹配剩的就看看能否和它的父亲匹配。
这道题的心得:
①遇到一眼就能看出大概的解题方向(或结论)的题目,多在草稿纸上画几个图。
②最重要的一点,这是一道构造题,必须要使局部的情况已经讨论完,才能进入下一级。就比如说从上往下匹配为什么不行。因为下面的状态情况还没有讨论完,且下面完全可能影响上面。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define N 100010 #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; struct note{ int to,next; };note edge[N*4]; struct note1{ int x,y,z; };note1 ans[N*2]; int i,j,k,l,n,m,now,gx,gy,u,v; int t,w,cnt; int e ,tot,T; int fa ,tar ; int head ; bool bz[N*4],vis ; void lb(int x,int y){ edge[++tot].to=y; edge[tot].next=head[x]; head[x]=tot; } void work(int S){ int t=0,T=1,i; fa[S]=-1; tar[1]=S; while(t<T){ now=tar[++t]; for(i=head[now];i;i=edge[i].next) if(!fa[edge[i].to]){ fa[edge[i].to]=now; tar[++T]=edge[i].to; } } while(T--){ now=tar[T+1]; e[0]=0; for(i=head[now];i;i=edge[i].next) if(!bz[i] && edge[i].to!=fa[now])e[++e[0]]=i; for(i=head[now];i;i=edge[i].next) if(!bz[i] && edge[i].to==fa[now])e[++e[0]]=i; for(i=1;i+1<=e[0];i+=2){ bz[e[i]]=bz[e[i]^1]=1; bz[e[i+1]]=bz[e[i+1]^1]=1; ans[++cnt].x=edge[e[i]].to; ans[cnt].y=now; ans[cnt].z=edge[e[i+1]].to; } } } int main(){ freopen("graph.in","r",stdin); freopen("graph.out","w",stdout); scanf("%d%d",&n,&m); tot=1; fo(i,1,m){ scanf("%d%d",&u,&v); lb(u,v);lb(v,u); } fo(i,1,n)if(!fa[i])work(i); printf("%d\n",cnt); fo(i,1,cnt)printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].z); return 0; }
相关文章推荐
- JZOJ 5404. 【NOIP2017提高A组模拟10.10】Graph
- 5404. 【NOIP2017提高A组模拟10.10】Graph
- 【JZOJ 5405】【NOIP2017提高A组模拟10.10】Permutation
- JZOJ 5405.【NOIP2017提高A组模拟10.10】Permutation
- JZOJ 5406. 【NOIP2017提高A组模拟10.10】Tree
- JZOJ5405. 【NOIP2017提高A组模拟10.10】Permutation
- JZOJ 5405. 【NOIP2017提高A组模拟10.10】Permutation
- [jzoj5406]【NOIP2017提高A组模拟10.10】Tree
- 【jzoj5405】【NOIP2017提高A组模拟10.10】【Permutation】
- [JZOJ5405]【NOIP2017提高A组模拟10.10】Permutation
- JZOJ100045. 【NOIP2017提高A组模拟7.13】好数
- JZOJ 100047. 【NOIP2017提高A组模拟7.14】基因变异
- JZOJ5372. 【NOIP2017提高A组模拟9.17】猫 链表+贪心+堆优化
- JZOJ5373. 【NOIP2017提高A组模拟9.17】信仰是为了虚无之人
- JZOJ 5329. 【NOIP2017提高A组模拟8.22】时间机器
- JZOJ5377. 【NOIP2017提高A组模拟9.19】开拓 DP
- JZOJ5385. 【NOIP2017提高A组模拟9.23】Carry 树上倍增
- JZOJ 4919. 【NOIP2017提高组模拟12.10】神炎皇
- jzoj5385. 【NOIP2017提高A组模拟9.23】Carry
- 【JZOJ4928】【NOIP2017提高组模拟12.18】A