zoukankan      html  css  js  c++  java
  • 有向图欧拉路模板

    纯dfs,但是由于按大部分板子上dfs,会导致某个点已经dfs过一部分边,但在其他层dfs时又会再次访问这些vis过的边,虽然不进行递归,但是仍然需要for循环过去判断vis,因此极限情况仍然比O(n+m)大很多,亲测cf508D上38组样例卡掉,46ms到2s T掉的差距。不过由于某条边访问过之后一定不会再访问,所以可以直接删去那条边,修改head值就行,这样就能做到O(n+m),额……大概吧

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<math.h>
     5 using namespace std;
     6 
     7 const int maxn=1005;        //点数
     8 const int maxm=1005*26;        //边数
     9 int head[maxn],size;
    10 int point[maxm],nxt[maxm],vis[maxm],ind[maxm];
    11 int id[maxn],od[maxn];
    12 int cnt;
    13 int ans[maxm];
    14 void init(){
    15     cnt=size=0;
    16     memset(head,-1,sizeof(head));
    17     memset(vis,0,sizeof(vis));
    18     memset(id,0,sizeof(id));
    19     memset(od,0,sizeof(od));
    20 }
    21 void adde(int a,int b,int index){
    22     point[size]=b;
    23     ind[size]=index;
    24     nxt[size]=head[a];
    25     head[a]=size++;
    26     od[a]++;id[b]++;
    27 }
    28 void dfs(int s){
    29     for(int i=head[s];~i;i=nxt[i]){
    30         if(!vis[i]){
    31             vis[i]=1;
    32             dfs(point[i]);
    33             ans[cnt++]=ind[i];
    34         }
    35     }
    36 }
    37 //边数较多的图中可能重复遍历已经访问过的边会T,访问一条边直接删一条边可以更加快速
    38 /*
    39 void dfs(int s){
    40     while(~head[s]){
    41         int i=head[s];
    42         head[s]=nxt[i];
    43         dfs(point[i]);
    44         ans[cnt++]=ind[i];
    45     }
    46 }
    47 */
    48 void solve(int n,int m){        //n点m边
    49     int c1=0,c2=0,stx=1;        //stx取标号最小的节点
    50     for(int i=1;i<=n;i++){
    51         if(od[i]-id[i]==1)c1++,stx=i;
    52         else if(od[i]-id[i]==-1)c2++;
    53         else if(od[i]-id[i]!=0)c1=3;
    54     }
    55     if(!((c1==0&&c2==0)||(c1==1&&c2==1))){
    56         printf("NO
    ");
    57         return;
    58     }
    59     dfs(stx);
    60     if(cnt!=m){
    61         printf("NO
    ");
    62         return;
    63     }
    64     printf("YES
    ");
    65     for(int i=cnt-1;i>=0;--i){
    66         printf("%d ",ans[i]);
    67     }
    68     printf("
    ");
    69 }
  • 相关阅读:
    ubuntu实时显示网速cpu占用和内存占用率
    删除以....开头的所有文件
    0.0.....1 至 0.99.......9 之间正则
    引入腾讯视频播放,可控制是否暂停播放
    解决微信小程序textarea层级太高遮挡其他组件的问题
    查看某分支推送记录
    小程序下载canvas生成图片
    微信小程序企业付款到个人
    秒 转化为 时:分:秒 ------- 类似倒计时
    iOS--崩溃日志的格式化分析---格式化crash日志
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/6006331.html
Copyright © 2011-2022 走看看