ccf 送货
2016-04-05 20:08
218 查看
题意:无向图输出字典序最小的欧拉路径或者回路,如果没有就输出-1.
这题着实是应该记录一下我的心路历程,比赛的时候忘记字典序了,随便套了一个板子,结果0分。。。
然后oj挂出题后开始改,写了个很sb的dfs,10分,然后发现有两个奇数节点的时候应该起点为奇数度那个,改了,20分,然后随便给一组双环的样例,发现dfs写的有问题,应该回溯,改完80分,T了,我就好奇这怎么会T,没敢想是回溯的问题,就把1000次vector排序改了,改成1次排序,中间也有sb错误,比如边的序号标错等等,中间还试了map+pair的方法,无奈复杂度太高,还是T,然后发现记录一下id就行了,然后发现还是T,无奈发现肯定时不应该回溯,然后上网找到了erlu那个板子,发现确实是不需要回溯,然后改了之后100分!
这道题目让我发现,ccf这个东西确实是需要很给力的数据,然后相应的板子是一定要具备的,至少可以优化我自己那屌丝的方法,一定要各种细致!!!
先判断掉不合法的情况,即图不连通或者奇数度节点不为0或2,然后边排序搜,倒序输出就可以了(因为此时一定存在解)!
这题着实是应该记录一下我的心路历程,比赛的时候忘记字典序了,随便套了一个板子,结果0分。。。
然后oj挂出题后开始改,写了个很sb的dfs,10分,然后发现有两个奇数节点的时候应该起点为奇数度那个,改了,20分,然后随便给一组双环的样例,发现dfs写的有问题,应该回溯,改完80分,T了,我就好奇这怎么会T,没敢想是回溯的问题,就把1000次vector排序改了,改成1次排序,中间也有sb错误,比如边的序号标错等等,中间还试了map+pair的方法,无奈复杂度太高,还是T,然后发现记录一下id就行了,然后发现还是T,无奈发现肯定时不应该回溯,然后上网找到了erlu那个板子,发现确实是不需要回溯,然后改了之后100分!
这道题目让我发现,ccf这个东西确实是需要很给力的数据,然后相应的板子是一定要具备的,至少可以优化我自己那屌丝的方法,一定要各种细致!!!
先判断掉不合法的情况,即图不连通或者奇数度节点不为0或2,然后边排序搜,倒序输出就可以了(因为此时一定存在解)!
#include<bits/stdc++.h> using namespace std; #define pi pair<int,int> #define fi first #define se second const int maxn=1e5+10; int vis1[maxn]; int path[(int)2e6+10],cc; int n,m;int vis[(int)2e6+10],degree[maxn]; vector<pi>a[maxn]; map<pi,int>mm;int kk; struct node{ int u,v,id; }b[(int)1e6+10]; void dfs1(int u){ for(int i=0;i<a[u].size();i++){ int v=a[u][i].fi; if(vis1[v]) continue; vis1[v]=1; dfs1(v); } } int flag; void dfs2(int u){ //path[kk]=u; for(int i=0;i<a[u].size();i++){ int v=a[u][i].fi; if(vis[a[u][i].se]) continue; vis[a[u][i].se]=1;vis[a[u][i].se^1]=1; dfs2(v); path[kk++]=v; } } bool cmp(node a,node b){ if(a.u==b.u)return a.v<b.v; return a.u<b.u; } int main(){ scanf("%d%d",&n,&m);cc=1;int u,v; kk=2;flag=0; for(int i=1;i<=2*m-1;i+=2){ scanf("%d%d",&b[i].u,&b[i].v); // a[u].push_back({v,kk++});a[v].push_back({u,kk++}); degree[b[i].u]++;degree[b[i].v]++;b[i].id=i-1; b[i+1].u=b[i].v;b[i+1].v=b[i].u;b[i+1].id=i; } sort(b+1,b+1+2*m,cmp); for(int i=1;i<=2*m;i++){ int u=b[i].u;int v=b[i].v;int num=b[i].id; // cout<<" u = "<<u<<" v= "<<v<<"i d = "<<num<<endl; a[u].push_back({v,num}); } vis1[1]=1; dfs1(1); for(int i=1;i<=n;i++){ if(!vis1[i]){ puts("-1");return 0; } } int sum=0; for(int i=1;i<=n;i++){ if(degree[i]&1){ if(cc==1){ path[cc++]=i; } sum++; } } if(sum!=0&&sum!=2){ puts("-1");return 0; } if(cc==1){ path[cc++]=1; } dfs2(path[1]); printf("%d ",path[1]); for(int i=m+1;i>2;i--){ printf("%d ",path[i]); } printf("%d\n",path[2]); return 0; } /* 5 6 1 2 1 3 2 3 3 4 4 5 3 5 */
相关文章推荐