#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <climits> #include <algorithm> #define MAXN 200007 #define REP(i,b,e) for(int i=b;i<e;i++) #define DEBUG if(0) using namespace std; class POINT{public: vector<int> next; int mark; POINT(){RESET();} void RESET(){mark=0;next.clear();} }p[MAXN]; int INDEX,from[MAXN],fnum=0,to[MAXN],tnum=0,flag,list[MAXN],lnum; int dfs(int ind){ if(!p[ind].mark) p[ind].mark=INDEX++; else {DEBUG{cout<<ind<<"-="<<p[ind].mark<<endl;};return 0;}//如果重复标号 REP(i,0,p[ind].next.size()){ DEBUG cout<<p[ind].next[i]<<" "; if(!dfs(p[ind].next[i]))return 0; } return 1; } int main(){ int a,b,CASE=1; void init(); while(scanf("%d %d",&a,&b),a+b>=0){ init(); do{ //if(a==b && a!=0)continue; if(a==0 && b==0)break; DEBUG cout<<a<<"->"<<b<<endl; int flag2=0; REP(findi,0,p[a].next.size()){ if(p[a].next[findi]==b){ flag2=1;break; } }if(flag2)continue; p[a].next.push_back(b); from[fnum++]=a; to[tnum++]=b; list[lnum++]=a; list[lnum++]=b; }while(scanf("%d %d",&a,&b)); REP(fi,0,fnum){ REP(ti,0,tnum){ if(from[fi]==to[ti]){ from[fi]=0; }//筛选0入度点 } } int rec=0; REP(fi,0,fnum){ if(from[fi]>0){ if(rec==0){ rec=from[fi]; }else if(rec==from[fi]){ from[fi]=0;continue; }else{//出现两个0入度点 flag=0; DEBUG cout<<from[fi]<<"+"<<endl; break; } flag=dfs(from[fi]); if(!flag){ DEBUG cout<<from[fi]<<"="<<endl; break; } } } REP(i,0,lnum){ //确保全部标号 int t=list[i]; if(t>0 && !p[t].mark){ flag=0; DEBUG cout<<t<<"-"<<endl; } } REP(i,0,lnum)if(list[i]>0)p[list[i]].RESET(); printf("Case %d is%s a tree.\n",CASE++,flag?"":" not"); } return 0; } void init(){ INDEX=1;fnum=tnum=lnum=0;flag=1; }
https://vjudge.net/contest/384914#problem/C