本文已参与[新人创作礼]活动,一起开启掘金创作之路
题目描述
这是4月26日代码源div2的每日一题。
排队 - 题目 - Daimayuan Online Judge
请判断有没有一种方法可以将编号从 1 到 N 的 N 个人排成一排,并且满足给定的 M 个要求。
对于每个要求会给出两个整数 Ai 和 Bi,表示编号 Ai 和 Bi 的人是相邻的。
保证每个要求都不同,比如已经给出了 1,5,就不会再给出 1,5 或 5,1。
输入格式
第一行两个整数 N 和 M,表示 N 个人和 M 个要求。
输出格式
如果有一种能把这些人拍成一排并满足所有条件的方法,就输出 Yes,否则,输出 No。
样例输入1
4 2
1 3
2 3
样例输出1
Yes
样例输入2
4 3
1 4
2 4
3 4
样例输出2
No
样例输入3
3 3
1 2
1 3
2 3
样例输出3
No
数据规模
对于全部数据保证 2≤N≤10^5,0≤M≤10^5,1≤Ai<Bi≤N。
问题解析
对于这里的排队要求,一共有三种可能违法的情况:
1是整体是一个圈,此时每个点都至少被两个边连着。
2是有形成圈的情况,此时至少有一个点被三条边连着。
3是可能分成两个不相接的两部分(题目并没有说每个点都有要求),一个是正常的队列,一个是环。
我们先根据题目要求把所有边都连上,然后看形成的图的形状。如果有一个点被三条边连着,满足第二个条件,输出no;如果没有点是只被一条边连着,满足第一个条件,输出no。
第三个条件就比较麻烦了,我们可以先找到所有只被一条边连着的点,然后以这些点为起点遍历图,如果最后有点在提问中出现过,但没有在这次遍历中被遍历到,说明那些点自成一个环了(由于不和我们的边连着,所以遍历不到),输出no。
其余情况都输出yes。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 100500;
int main()
{
int n, m;
cin >> n >> m;
bool flag = true;
unordered_map<int, vector<int>>mymap;
unordered_map<int, int>cnt;
while (m--)
{
int a, b;
cin >> a >> b;
cnt[a] = 1;
cnt[b] = 1;
if (mymap[a].size() == 2)
{
cout << "No";
return 0;
}
mymap[a].push_back(b);
if (mymap[b].size() == 2)
{
cout << "No";
return 0;
}
mymap[b].push_back(a);
}
vector<int>st;
for (auto i : mymap)
{
if (i.second.size() > 2)
{
cout << "NO";
return 0;
}
if (i.second.size() == 1)
{
st.push_back(i.first);
}
}
int len = st.size();
if (len == 0&&mymap.size()!=0)
{
cout << "No";
return 0;
}
for (int i = 0; i < len; i++)
{
cnt[st[i]] = 0;
int x = st[i], y = mymap[st[i]][0];
cnt[y] = 0;
while (1)
{
if (mymap[y].size() != 1)break;
else if (mymap[y][0] != x)
{
cnt[mymap[y][0]] = 0;
x = y;
y = mymap[y][0];
}
else
{
cnt[mymap[y][1]] = 0;
x = y;
y = mymap[y][1];
}
}
}
for (auto i : cnt)
{
if (i.second == 1)
{
cout << "No";
return 0;
}
}
cout << "Yes";
return 0;
}