• uva 10054 The Necklac(欧拉回路)


    明显的欧拉回路,把颜色作为点,建图后,做一遍欧拉回路。不过我是现学的,打印路径上纠结了一下,发现随着FindEuler()的递归调用的结束,不断把点压入栈中,从后向前打印,遇到"支路"会先处理好支路再继续的。这样就可以顺序打印路径了。如果是直接打印或放在队列里,会发现打印出来的项链的关系正好相反,即前一行的第一个与本行的第二个颜色相同。

    邻接表又开小了,MAXN<<1 。还有就是用STL的栈TLE了,还是手写吧= =

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stack>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 const int MAXN=55;
      8 const int MAXM=1111;
      9 
     10 int sta[MAXM][2],top;
     11 
     12 struct Edge{
     13     int v,next;
     14     int vis;
     15     Edge(){}
     16     Edge(int _v,int _next):v(_v),next(_next),vis(0){}
     17 }edge[MAXM<<1];
     18 
     19 int tol,head[MAXN],E;
     20 int degree[MAXN];
     21 
     22 void init()
     23 {
     24     tol=0;E=0;
     25     memset(head,-1,sizeof(head));
     26     memset(degree,0,sizeof(degree));
     27 }
     28 
     29 void add(int u,int v)
     30 {
     31     edge[tol]=Edge(v,head[u]);
     32     head[u]=tol++;
     33 }
     34 
     35 int FindVertex(){
     36     for(int i=1;i<=50;i++)
     37     {
     38         if(degree[i])
     39             return i;
     40     }
     41     return -1;
     42 }
     43 
     44 void FindEuler(int u)
     45 {
     46     for(int i=head[u];i!=-1;i=edge[i].next)
     47     {
     48         int v=edge[i].v;
     49         if(!edge[i].vis){
     50             edge[i].vis=edge[i^1].vis=1;
     51 
     52             FindEuler(v);
     53             sta[top][0]=u;
     54             sta[top++][1]=v;
     55         }
     56     }
     57 }
     58 
     59 bool EulerCircuit()
     60 {
     61     for(int i=0;i<=50;i++)
     62         if(degree[i]%2!=0)
     63             return false;
     64     int s=FindVertex();
     65     if(s==-1)
     66         return false;
     67 
     68     top=0;
     69     FindEuler(s);
     70 
     71     if(top!=E)
     72         return false;
     73     return true;
     74 
     75 }
     76 
     77 int main()
     78 {
     79     int T,k,n;
     80     int a,b;
     81     scanf("%d",&T);
     82     for(k=1;k<=T;k++)
     83     {
     84         scanf("%d",&n);
     85 
     86         init();
     87         for(int i=0;i<n;i++)
     88         {
     89             scanf("%d%d",&a,&b);
     90             add(a,b);
     91             add(b,a);
     92             E++;
     93             degree[a]++;
     94             degree[b]++;
     95         }
     96 
     97         if(k!=1)
     98             puts("");
     99         printf("Case #%d
    ",k);
    100         if(EulerCircuit()){
    101             while(top!=0){
    102                 top--;
    103                 printf("%d %d
    ",sta[top][0],sta[top][1]);
    104             }
    105         }else
    106             printf("some beads may be lost
    ");
    107     }
    108     return 0;
    109 }
    View Code

     补充:用邻接表打印字典序最小的回路,应该在建图后对每个adjacency list 排序。

        如果在有向图上做欧拉回路,只需把判断偶点改为出入度相等即可。

        Euler Trail与Euler Circuit 最多相差一条边(回路本身也是一条迹),所以把判断偶点改为恰有两个奇点或没有奇点即可。

  • 相关阅读:
    CSS 兼容性调试技巧
    CSS 常用的兼容性调试技巧
    全局CSS设置
    CSS 盒子模型
    CSS表格属性
    HTML引入CSS的方法
    CSS 定位
    CSS display overflow 属性 cursor光标类型
    CSS 继承和优先级
    沟通表达
  • 原文地址:https://www.cnblogs.com/zstu-abc/p/3228478.html
Copyright © 2020-2023  润新知