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;
}

  

posted @ 2015-09-13 19:15  Claris  阅读(225)  评论(0编辑  收藏  举报