zoukankan      html  css  js  c++  java
  • BZOJ1515 : [POI2006]Lis-The Postman

    首先,如果这个图本身就不存在欧拉回路,那么显然无解。

    对于每个子串:

    1.如果里面有不存在的边,那么显然无解。

    2.如果里面有一条边重复出现,那么显然也无解。

    3.对于每条边,维护其前驱与后继,若前驱或后继超过$1$个,那么显然也无解。

    如此所有边将形成一条条链或者环的结构,如果存在环,那么显然也无解。

    对于每条链,在新图中添加链头到链尾的边,然后判断新图中是否存在从$1$开始的欧拉回路即可。

    时间复杂度$O(mlog m)$。

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    const int N=50010,M=200010;
    int n,m,q,i,j,k,pos,cnt,d[N],a[M],b[M],last[M],pre[M],nxt[M];
    int g[N],V[M],W[M],NXT[M],vis[M],ed;
    struct E{int x,y;}e[M];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline bool cmp(const E&a,const E&b){return a.x==b.x?a.y<b.y:a.x<b.x;}
    void NIE(){puts("NIE");exit(0);}
    inline int ask(int x,int y){
      int l=1,r=m,mid;
      while(l<=r){
        mid=(l+r)>>1;
        if(e[mid].x==x&&e[mid].y==y)return mid;
        if(e[mid].x<x||e[mid].x==x&&e[mid].y<y)l=mid+1;else r=mid-1;
      }
      return 0;
    }
    inline void add(int x,int y,int z){d[x]++,d[y]--;V[++ed]=y;W[ed]=z;NXT[ed]=g[x];g[x]=ed;}
    void dfs(int x){
      for(int&i=g[x];i;){
        if(vis[i]){i=NXT[i];continue;}
        vis[i]=1;
        dfs(V[i]);
      }
    }
    int main(){
      read(n),read(m);
      for(i=1;i<=m;i++)read(e[i].x),read(e[i].y),d[e[i].x]++,d[e[i].y]--;
      for(i=1;i<=n;i++)if(d[i])NIE();
      sort(e+1,e+m+1,cmp);
      read(q);
      for(pos=1;pos<=q;pos++){
        read(k);
        for(i=1;i<=k;i++)read(a[i]);
        for(i=1;i<k;i++){
          b[i]=ask(a[i],a[i+1]);
          if(!b[i])NIE();
          if(last[b[i]]==pos)NIE();
          last[b[i]]=pos;
        }
        for(k--,i=1;i<k;i++){
          if(!nxt[b[i]])nxt[b[i]]=b[i+1];
          else if(nxt[b[i]]!=b[i+1])NIE();
          if(!pre[b[i+1]])pre[b[i+1]]=b[i];
          else if(pre[b[i+1]]!=b[i])NIE();
        }
      }
      for(i=1;i<=n;i++)d[i]=0;
      for(i=1;i<=m;i++)if(!pre[i]){
        for(k=0,j=i;j;j=nxt[j])a[++k]=j,cnt++;
        add(e[i].x,e[a[k]].y,a[k]);
      }
      if(cnt<m)NIE();
      if(!g[1])NIE();
      for(i=1;i<=n;i++)if(d[i])NIE();
      dfs(1);
      for(i=2;i<=n;i++)if(g[i])NIE();
      return puts("TAK"),0;
    }
    

      

  • 相关阅读:
    mybatis 动态sql
    linux shell 之 crontab(定时任务)详解
    FTP定时批量下载文件(SHELL脚本及使用方法 )
    腾讯云数据库团队:MySQL5.7 JSON实现简单介绍
    Chisel Tutorial(七)——模块
    大数问题解决模板
    可靠的功能測试--Espresso和Dagger2
    hdoj 1698 Just a Hook 【线段树 区间更新】
    平衡二叉树
    WPF中DependencyObject与DependencyProperty的源代码简单剖析
  • 原文地址:https://www.cnblogs.com/clrs97/p/6383327.html
Copyright © 2011-2022 走看看