题目链接 https://vjudge.net/problem/HDU-3478
题意:给定一个图和起点,每分钟走1条边,不能休息,可以重复走边,问是否能在某个时刻时,无法判断现在在哪个店。
题解:参考 http://www.cppblog.com/Yuan/archive/2010/08/11/123005.html
对于任意点,假设其单源最短路径长度为x,加入没有环,则只能在x+2k(k=0,1,2,3...)时刻到达该点,假设x是5,则时刻是5,7,9,11,不难想到,都是奇数,所以如果不考虑环的话,某个时刻,一定可以到达所有奇数最短路径或偶数最短路径的点,不能同时到2个为奇数和偶数的点,所以应该有环才行,而且得是奇数环,这样最短路径为奇数的点,进环里面绕一圈就可以在偶数时刻到达。判断奇数环可以采用DFS的方法,如果当前点的邻接节点访问过且不是父亲点,则说明有环。。。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e5+10;
vector<int> G[maxn];
bool flag;
int vi[maxn];
void dfs(int u, int p, int dep) {
if(flag) return;
vi[u] = dep;
for(int i = 0, size=G[u].size();i < size;i++) {
int v = G[u][i];
if(v == p) continue;
if(vi[v] == dep) {flag = true;return;};
if(vi[v] == 0) dfs(v, u, -dep);
}
}
int main() {
int t, T;
t=1;
scanf("%d", &T);
while(T--) {
printf("Case %d: ", t++);
int n, m, s;
scanf("%d%d%d", &n, &m, &s);
for(int i = 0;i < n;i++) {
G[i].clear();
}
for(int i=0, a, b;i < m;i++) {
scanf("%d%d", &a, &b);
G[a].push_back(b);
G[b].push_back(a);
}
memset(vi, 0, sizeof vi);
flag = false;
dfs(s, s, 1);
puts(flag?"YES":"NO");
}
return 0;
}