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 件のコメント:
コメントを投稿