Kids’ Wishes
.
.
题意:给出n个小朋友,m个要求,要求 x 和 y 坐在一起,问是否可能。
.
.
解法:首先坐在一起的互连一条有向边,然后判断如果有点的度数大于2那么一定不行,如果图中存在一个小于n的环,那么一定不行。
.
.
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <cstring>
using namespace std;
const int maxe=1e5+5;
const int maxn=2*maxe;
const int INF=1e9+5;
int k, w, len;
vector<int> g[maxn];
int u[maxn], v[maxn], d[maxn], f[maxn];
set<pair<int, int> > m;
void init() {
for (int i=0; i<maxn; i++) g[i].clear();
memset(d, -1, sizeof(d));
len=INF;
m.clear();
}
int b[maxn], cnt;
void bfs(int s) {
queue<int> Q;
Q.push(s); d[s]=0; f[s]=-1;
while (!Q.empty()) {
int u=Q.front(); Q.pop();
for (int i=0; i<g[u].size(); i++) if (g[u][i]!=f[u]) {
int v=g[u][i];
if (d[v]==-1) {
d[v]=d[u]+1;
f[v]=u;
Q.push(v);
}
else {
len=min(len, d[v]+d[u]+1);
}
}
}
}
inline int getid(int x) {return lower_bound(b, b+cnt, x)-b;}
int main() {
while (scanf("%d%d", &k, &w)==2) {
if (!k&&!w) return 0;
init();
for (int i=0; i<w; i++) {
scanf("%d%d", u+i, v+i);
b[2*i]=u[i], b[2*i+1]=v[i];
}
cnt=2*w;
sort(b, b+cnt);
cnt=unique(b, b+cnt)-b;
bool flag=true;
for (int i=0; i<w; i++) {
u[i]=getid(u[i]), v[i]=getid(v[i]);
m.insert(make_pair(u[i], v[i]));
m.insert(make_pair(v[i], u[i]));
}
for (set<pair<int, int> >::iterator it=m.begin(); it!=m.end(); it++) {
int x=it->first, y=it->second;
g[x].push_back(y);
if (g[x].size()>2) flag=false;
}
if (flag) {
for (int i=0; i<cnt; i++) if (d[i]==-1) bfs(i);
// cout << len << endl;
if (len<k) flag=false;
}
puts(flag?"Y":"N");
}
}