1134:Name the Crossing

東西方向と南北方向に走る通りの名前の付け方が
ありうるかどうか判定する問題。

通りが平行でないかはグラフを2色に彩色して
色が異なっているかで判定。

水準の判定は、

交差点の入力にA-BがあればA→Bの辺を張り、
AとBが同水準ならA→BとA←Bの辺を張る。
このグラフでワーシャルフロイドして、
graph[A][B]があればAはB以上の水準となる。

#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<algorithm>
  
#define all(a) (a).begin(),(a).end()
#define pb(a) push_back((a))
#define mp(a,b) make_pair((a),(b))
#define fst first
#define sec second
  
using namespace std;

multimap<string,string>m1,m2;
map<string,int>color;
int graph[200][200];

void split(string in,string& s1,string& s2){
  for(int i=0;i<in.size();i++){
    if(in[i]=='-'){
      s1=in.substr(0,i);
      s2=in.substr(i+1,in.size()-i-1);
      return;
    }
  }
}
  
void dfs(string v,int c){
  color[v]=c;
  multimap<string,string>::iterator it=m2.begin();
  while(it!=m2.end()){
    if((*it).fst==v && color[(*it).sec]==0)dfs((*it).sec,-c);
    it++;
  }
}

void warshall_floyd(int V){
  for(int k=0;k<V;k++)
    for(int i=0;i<V;i++)
      for(int j=0;j<V;j++)
	graph[i][j]|=graph[i][k]&graph[k][j];
}

int main(void){
  int n,m;
  string in,s1,s2;
  vector<string>node,node3;
  map<string,int>node2;
  vector<pair<string,string> >query;
  
  while(cin >> n,n){
    m1.clear();
    m2.clear();
    color.clear();
    node.clear();
    node2.clear();
    node3.clear();
    query.clear();
    
    for(int i=0;i<n;i++){
      cin >> in;
      split(in,s1,s2);
      node.pb(s1);
      node.pb(s2);
      node3.pb(s1);
      node3.pb(s2);
      m1.insert(mp(s1,s2));
      m2.insert(mp(s1,s2));
      m2.insert(mp(s2,s1));
    }
    sort(all(node));
    node.erase(unique(all(node)),node.end());
    
    cout << node.size() << endl;
    
    cin >> m;
    for(int i=0;i<m;i++){
      cin >> in;
      split(in,s1,s2);
      query.pb(mp(s1,s2));
      node3.pb(s1);
      node3.pb(s2);
    }
    
    sort(all(node3));
    node3.erase(unique(all(node3)),node3.end());
    
    for(int i=0;i<node3.size();i++){
      color[node3[i]]=0;
      node2[node3[i]]=i;
    }
    
    for(int i=0,j=1;i<node3.size();i++)
      if(color[node3[i]]==0)dfs(node3[i],j++);
    
    bool g[200][200];
    for(int i=0;i<200;i++){
      for(int j=0;j<200;j++){
	g[i][j]=false;
	graph[i][j]=i==j?1:0; 
      }
    }
    
    multimap<string,string>::iterator it,it2;
    
    for(it=m1.begin();it!=m1.end();it++){
      for(it2=m1.begin();it2!=m1.end();it2++){
	if(it==it2)continue;

	if((*it).fst==(*it2).sec){
	  g[node2[(*it).sec]][node2[(*it2).fst]]=true;
	  g[node2[(*it2).fst]][node2[(*it).sec]]=true;
	}
	if((*it).sec==(*it2).fst){
	  g[node2[(*it).fst]][node2[(*it2).sec]]=true;
	  g[node2[(*it2).sec]][node2[(*it).fst]]=true;
	}
      }
    }
    
    for(it=m1.begin();it!=m1.end();it++){
      graph[node2[(*it).fst]][node2[(*it).sec]]=1;
        
      for(it2=m1.begin();it2!=m1.end();it2++){
	if(it==it2)continue;
	
	if((*it).fst==(*it2).fst && !g[node2[(*it).sec]][node2[(*it2).sec]]){
	  graph[node2[(*it).sec]][node2[(*it2).sec]]=1;
	  graph[node2[(*it2).sec]][node2[(*it).sec]]=1;
	}
	if((*it).sec==(*it2).sec && !g[node2[(*it).fst]][node2[(*it2).fst]]){
	  graph[node2[(*it).fst]][node2[(*it2).fst]]=1;
	  graph[node2[(*it2).fst]][node2[(*it).fst]]=1;
	}
      }
    }
    
    warshall_floyd(node3.size());
    
    for(int i=0;i<query.size();i++){
      if(color[query[i].fst]+color[query[i].sec]==0 &&
	 graph[node2[query[i].fst]][node2[query[i].sec]]==1)
	cout << "YES" << endl;
      else cout << "NO" << endl;
    }
  }
  return 0;
}