BZOJ3724: PA2014Final Krolestwo
来源:互联网 发布:外星人源码论坛eenot 编辑:程序博客网 时间:2024/06/07 08:40
跪dalao……
我们新建一个点0,连边向所有奇数度点,于是得到了一个偶数条边,所有点度数都是偶数的图
这个图存在欧拉回路,根据每次流出0,流入0的两个奇数点可以配对
但是这题要求路径长度为偶数,于是我们将n个点拆成2n个点,这样配对的奇数点之间的路径长度就是偶数了
我们现在想在2n个点中建入原图中的边,使所有点度数都为偶数
考虑怎么连原图中的边
0的度数显然为偶数
建出原图的生成树,对于不在生成树上的边,在二分图上随便建
然后对于生成树上的边 < fa,x>,
如果x的度数是奇数,连边< x,fa+n>
如果x的度数是偶数,连边< x+n,fa>
这样做能保证x的度数是偶数,因为拆点前x的度数是偶数,所以x+n的度数一定是偶数
于是我们能保证除了树根的两个点root,root+n,所有点的度数都是偶数
因为所有点的度数和是偶数,
若他们都为奇数,则存在一条root到root+n的欧拉回路(好吧不能叫回?
因为原图的总边数是偶数,根据二分图性质,从root走完所有边一定在root这边,不合法
所以这种情况不存在
于是所有点度数都是偶数
跑个欧拉回路就好了qaq
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;inline void read(int &x){ char c; while(!((c=getchar())>='0'&&c<='9')); x=c-'0'; while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';}const int maxn = 1010000;const int maxm = 2010000;int n,m;int d[maxn],cnt[maxn],e[maxm][2];struct edge{int y,c,nex;}a[maxm]; int len,fir[maxn];inline void ins(const int x,const int y,const int c){ a[++len]=(edge){y,c,fir[x]};fir[x]=len; a[++len]=(edge){x,c,fir[y]};fir[y]=len; cnt[x]++,cnt[y]++;}int fa[maxn];int findfa(const int x){return fa[x]==x?x:fa[x]=findfa(fa[x]);}vector<int>V[maxn],vi[maxn];void build(const int x,const int fa,const int fai){ for(int i=0;i<V[x].size();i++) if(V[x][i]!=fa) build(V[x][i],x,vi[x][i]); if(x==1) return; if(cnt[x]&1) ins(x,fa+n,fai); else ins(x+n,fa,fai);}bool use[maxm];int t[maxm],tp;void dfs(const int x){ for(int k=fir[x];k;k=fir[x]) { while(k&&use[a[k].c]) k=a[k].nex; if(!k) return; use[a[k].c]=true; fir[x]=a[k].nex; dfs(a[k].y),t[++tp]=a[k].c; }}int main(){ read(n); read(m); for(int i=1;i<=m;i++) { int x,y; read(x); read(y); d[x]++,d[y]++; e[i][0]=x,e[i][1]=y; } for(int i=1;i<=n;i++) if(d[i]&1) ins(0,i,m+i); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++) { int x=e[i][0],y=e[i][1]; if(findfa(x)==findfa(y)) ins(x,y+n,i); else { fa[findfa(x)]=findfa(y); V[x].push_back(y),vi[x].push_back(i); V[y].push_back(x),vi[y].push_back(i); } } build(1,0,0); dfs(0); while(tp>0) { int ans1,ans2,ans3; ans1=t[tp--]-m; int j=tp;while(t[j]<=m) j--; ans2=t[j]-m; printf("%d %d %d\n",ans1,ans2,tp-j); while(tp>j) printf("%d ",t[tp--]); putchar('\n'); tp--; } return 0;}
阅读全文
0 0
- BZOJ3724: PA2014Final Krolestwo
- 【PA2014Final】【BZOJ3721】Bazarek
- 【bzoj3721】 PA2014Final Bazarek 贪心
- 【PA2014Final】【BZOJ3726】Wykladzina
- 【bzoj3728】 PA2014Final Zarowki
- 【bzoj3728】PA2014Final Zarowki
- BZOJ3728: PA2014Final Zarowki
- BZOJ3726: PA2014Final Wykladzina
- 3728: PA2014Final Zarowki set+priority_queue
- BZOJ 3728: PA2014Final Zarowki|贪心
- BZOJ 3728 PA2014Final Zarowki 堆+贪心
- 【PA】PA2014Final Wykładzina【单调栈+双指针+均摊分析】
- 阿里云Ubuntu16.04搭建LAMP+私有云nextcloud
- 请求重定向和请求转发的区别
- Spring学习笔记-MVC文件上传与下载
- Dubbo 结合 Spring Boot 的探索(注册发现,管理监控,全链路日志跟踪)
- codeforces 903A.Hungry Student Problem
- BZOJ3724: PA2014Final Krolestwo
- Shoppings
- HDU P2196 Computer
- BZOJ2815: [ZJOI2012]灾难(支配树)
- java通过克隆的方式创建对象
- 复数类
- 修改DLL文件内容
- 布局和简单的适配器
- PHP基础语法之文件操作