• BZOJ4065 : [Cerc2012]Graphic Madness


    因为两棵树中间只有k条边,所以这些边一定要用到。

    对于每棵树分别考虑:

    如果一个点往下连着两个点,那么这个点往上的那条边一定不能用到。

    如果一个点往下连着一个点,那么这个点往上的那条边一定不能用到。

    否则一定无解。

    这样求出所有一定要用到的边后,如果不存在奇点且这个图是个连通图的话,那么就有解。时间复杂度$O(n+m+k)$。

    #include<cstdio>
    #include<cstring>
    #define N 10010
    int T,k,n,m,i,d[N],vis[N],g[N],v[N],ok[N],nxt[N],ed,flag;char sa[N],sb[N];
    int getid(char s[]){
      int l=std::strlen(s),x=0;
      for(int i=2;i<l;i++)x=x*10+s[i]-'0';
      if(s[0]=='A'){
        if(s[1]=='S')return x;
        return x+k;
      }
      if(s[1]=='S')return x+k+n;
      return x+k*2+n;
    }
    void printname(int x){
      if(x<=k){printf("AS%d",x);return;}
      if(x<=k+n){printf("AP%d",x-k);return;}
      if(x<=k*2+n){printf("BS%d",x-k-n);return;}
      printf("BP%d",x-k*2-n);
    }
    void add(int x,int y){
      v[++ed]=y;ok[ed]=1;nxt[ed]=g[x];g[x]=ed;d[x]++;
      v[++ed]=x;ok[ed]=1;nxt[ed]=g[y];g[y]=ed;d[y]++;
    }
    int dfs1(int x,int y,int w){
      if(x<=k)return 1;
      if(x>k+n)return 0;
      int t=0;
      for(int i=g[x];i;i=nxt[i])if(v[i]!=y)t+=dfs1(v[i],x,i);
      if(!t||t>2)return flag=1,0;
      if(t==1)return 1;
      if(w)d[x]--,d[y]--,ok[w]=ok[w^1]=0;
      return 0;
    }
    int dfs2(int x,int y,int w){
      if(x>k+n&&x<=k*2+n)return 1;
      if(x<=k+n)return 0;
      int t=0;
      for(int i=g[x];i;i=nxt[i])if(v[i]!=y)t+=dfs2(v[i],x,i);
      if(!t||t>2)return flag=1,0;
      if(t==1)return 1;
      if(w)d[x]--,d[y]--,ok[w]=ok[w^1]=0;
      return 0;
    }
    void dfs3(int x){
      if(vis[x])return;
      vis[x]=1;
      for(int i=g[x];i;i=nxt[i])if(ok[i])dfs3(v[i]);
    }
    void dfs4(int x){
      if(vis[x])return;
      vis[x]=1;
      putchar(' ');printname(x);
      for(int i=g[x];i;i=nxt[i])if(ok[i])dfs4(v[i]);
    }
    int main(){
      scanf("%d",&T);
      while(T--){
        scanf("%d%d%d",&k,&n,&m);
        for(ed=i=1;i<=n+m+k*2;i++)g[i]=d[i]=vis[i]=0;flag=0;
        for(i=1;i<=n+m+k*3-2;i++)scanf("%s%s",sa,sb),add(getid(sa),getid(sb));
        dfs1(k+1,0,0),dfs2(k*2+n+1,0,0);
        for(i=1;i<=n+m+k*2;i++)if(d[i]&1)flag=1;
        dfs3(1);
        for(i=1;i<=n+m+k*2;i++)if(!vis[i])flag=1;
        if(flag)puts("NO");
        else{
          printf("YES");
          for(i=1;i<=n+m+k*2;i++)vis[i]=0;
          dfs4(1);
          puts("");
        }
      }
      return 0;
    }
    

      

  • 相关阅读:
    想想学习C已经有9年了, 应该可以写一些东西了.——转
    python gmail 多个收件人
    翻译_工具建议
    C语言的可变参数——转
    XP专业版中安装了IIS,配置好之后只能访问静态htm网页,图片之类的,但是ASP 文件确不能读取,提示无法显示网页提示
    ubuntu 修改IP,网关等
    java发送邮件
    在MyEclipse中配置Tomcat服务器
    国外程序员推荐:每个程序员都应读的书(转载)
    100个有关管理的网站
  • 原文地址:https://www.cnblogs.com/clrs97/p/4805395.html
Copyright © 2020-2023  润新知