yokobuttonの不定期で競技プログラミングをするブログ

不定期で解けた競技プログラミングコンテストの問題を載せています。

パナソニックプログラミングコンテスト2021(AtCoder Beginner Contest 231) D - Neighbors

問題の要約
 1からNの番号がついたN人を横一列に並べる方法のうち,以下の形式のM個の条件全てを満たすものが存在するか判定しろ。
  ・条件:人Aiと人Biは隣り合っている
制約
 2<=N<=10^5
 0<=M<=10^5
 1<=Ai<Bi<=N
 (Ai,Bi)は相異なる
入力
 N M
 A1 B1
 ...
 AM BM
考え方
 1,人の番号を1ずらす
  1<=i<=N => 0<=i<=N-1
 2,グラフで考える。
 3,(Ai,Bi)が相異なることからN<=Mならば必ず条件を満たすものは存在しない。
  なぜなら,N<=Mならばループが存在するから。
 4,横一列に並べるので,次数が2よりも大きい人が存在すると条件を満たすものが存在しない。
 5,そのほかにループが存在すると条件を満たすものが存在しない。
実際のプログラム
#include<iostream>
#include<vector>

using namespace std;

vector<vector<long long>> G;
vector<bool> visited;
bool flag;

void f(long long v, long long pre){
  if(visited[v] == true){
    flag = false;
    return;
  }
  visited[v] = true;
  for(long long i = 0; i < G[v].size(); i++){
    long long w = G[v][i];
    if(w == pre){
      continue;
    }
    f(w,v);
  }
  return;
}

int main(){
  long long N,M;
  cin >> N >> M;
  G.resize(N);
  for(long long i = 0; i < M; i++){
    long long A,B;
    cin >> A >> B;
    G[A-1].push_back(B-1);
    G[B-1].push_back(A-1);
  }
  visited.resize(N,false);
  flag = true;
  if(N <= M){
    flag = false;
  }
  for(long long i = 0; i < N; i++){
    if(2 < G[i].size()){
      flag = false;
      break;
    }
    if(visited[i] == true){
      continue;
    }
    f(i,-1);
  }
  
  if(flag){
    cout << "Yes" << endl;
  }else{
    cout << "No" << endl;
  }
  return 0;
}