パナソニックプログラミングコンテスト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;
}