2014年4月20日日曜日

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_B

GRL_3_Aのコードを9割流用して10分で解けた。
前の問題の解放を我流であみだすのに3日かかったことを考えるとあっという間であった。

お祈りは済ませたか?
コードのチェックは。
部屋の隅で胸をドキドキさせながらジャッジデータを通ることを祈る心の準備は?

OKだ。
というわけで一発で通りました。
問題的には3Aとほとんど同じでした。




#include<stdio.h>
#include<queue>
#include<map>
#include<vector>
#include<string.h>
#include<algorithm>
#include<set>
#include<stack>

struct E{
      int t,len,old,no;
      bool alive;
      bool operator<(const E& e1)const{
            return len>e1.len;
      }
};

const int LIMIT=10*10000+1;
std::vector<E> G[LIMIT];
int lens[LIMIT];
int roots[LIMIT];

bool alivePoints[LIMIT];
int  loopCounts[LIMIT];
int size;


void D(){
      E e1,e2;
      int v,e,s,t;
      scanf("%d %d",&v,&e);
     
      for(int i=0;i<e;i++){
            scanf("%d %d",&s,&t);
            e1.alive=false;
            e1.len=0;
            e1.t=t;
            G[s].push_back(e1);
            e1.t=s;
            G[t].push_back(e1);
      }
      memset(lens,-1,sizeof(lens));
      e1.old=-1;
      e1.t=0;
      e1.len=0;
      e1.no=0;
      std::priority_queue<E> pq;
      pq.push(e1);
      std::vector<E>::iterator vIt,vItEnd;
      size=v;
      while(pq.empty()==false){
            e1=pq.top();
            pq.pop();
            if(lens[e1.t]!=-1&&lens[e1.t]<=e1.len){    
                  continue;
            }
            lens[e1.t]=e1.len;
           
            if(e1.old!=-1){
                  //printf("(a t=%d old=%d no=%d)\n",e1.t,e1.old,e1.no);
                  G[e1.old][e1.no].alive=true;
                  roots[e1.t]=e1.old;
            }
           
            e1.len++;
            vItEnd=G[e1.t].end();
            int i=0;
            for(vIt=G[e1.t].begin();vIt!=vItEnd;vIt++){
                  e2=(*vIt);
                  e2.len=e1.len;
                  e2.old=e1.t;
                  e2.no=i;
                  i++;
                  if(e2.t==e1.old){
                        //printf("(b old=%d t=%d no=%d)\n",e2.old, e2.t, e2.no);
                        G[e2.old][e2.no].alive=true;
                  }else{
                        pq.push(e2);
                  }
            }
      }
      //std::set<int>::iterator sIt;
      //for(int i=0;i<v;i++){
      //      printf("\n%d\n",i);
      //      for(sIt=pareMemo[i].begin();sIt!=pareMemo[i].end();sIt++){
      //            printf("<%d> ",(*sIt));
      //      }
      //}
}


std::map<int,int> memo;
int countNos[LIMIT];
int nowLoopAdds[LIMIT];
int dells[LIMIT];
bool cutOKs[LIMIT];
std::set<std::pair<int,int> > ans;


void search(){
      memset(alivePoints,true,sizeof(alivePoints));
      memset(loopCounts,0,sizeof(loopCounts));
      memset(nowLoopAdds,0,sizeof(nowLoopAdds));
      memset(dells,0,sizeof(dells));

      std::stack<std::pair<int,int> > sta;
      std::pair<int,int> pp,pp2,pp3;
      alivePoints[0]=false;
      pp.first=0;
      pp.second=0;
      sta.push(pp);
      std::vector<E>::iterator vIt,vItEnd;
      E e1;
      int countNo=0;
      while(sta.empty()==false){
            countNo++;
            pp=sta.top();
            sta.pop();
           
            int s=pp.first;
            int i=pp.second;
            //printf("%d ",s);
            alivePoints[s]=false;
            if(i==G[s].size()){
                  int t=countNos[s];
                  memo.erase(t);
                  if(s!=0){
                        loopCounts[roots[s]]+=loopCounts[s]+nowLoopAdds[s]-dells[s];
                        if((loopCounts[s]==dells[s])&&((nowLoopAdds[s]+loopCounts[s]==0)||(dells[s]>0))){
                              if(cutOKs[s]==true){
                                    pp3.first=std::min(s,roots[s]);
                                    pp3.second=std::max(s,roots[s]);
                                    ans.insert(pp3);
                              }
                        }
                  }
                 
                  //printf("\n<d=%d>\n",t);
                  //std::map<int,int>::iterator sIt;
                  //for(sIt=memo.begin();sIt!=memo.end();sIt++){
                  //      printf("<%d %d>",(*sIt).first,(*sIt).second);
                  //}
                  //printf("\n");
            }else{
                  if(i==0){
                        memo[countNo]=s;
                        cutOKs[s]=true;
                  }else{
                        int t=countNos[s];
                        memo.erase(t);
                        memo[countNo]=s;
                  }
                  countNos[s]=countNo;
                 
                  e1=G[s][pp.second];
                  pp.second++;
                  sta.push(pp);
                  if(roots[s]!=e1.t && lens[e1.t]<=lens[s]){
                        cutOKs[s]=false;
                  }
                 
                  if(e1.alive==false&&alivePoints[e1.t]==true){
                        nowLoopAdds[s]++;
                  }
                 
                  if(alivePoints[e1.t]==false&&e1.alive==false){
                        int dellP=(*(memo.upper_bound(countNos[e1.t]))).second;
                        nowLoopAdds[s]++;
                        //printf("\n<dell=%d t=%d s=%d>\n",dellP,e1.t,s);
                        dells[dellP]+=2;
                        continue;    
                  }
                  if(alivePoints[e1.t]==false){
                        continue;
                  }
                  if(e1.alive==true){
                        pp2.first=e1.t;
                        pp2.second=0;
                        sta.push(pp2);
                  }
            }
      }
      std::set<std::pair<int,int> >::iterator it;
      for(it=ans.begin();it!=ans.end();it++){
            printf("%d %d\n",(*it).first,(*it).second);
      }
}

int main(){
      D();
      search();
}

0 件のコメント:

コメントを投稿