题目:一个图,源点有三个,每个点被遍历的条件是这个点和三个已经遍历过的点相连!初始的时候,有三个点是已经遍历过的,问每个点被遍历的时间!
分析:我选择广度优先搜索。对每一个和遍历过的点相连的进行判断,判断是否和三个以上的遍历过的点相连,如果是,那么把它加入队列,同时它wake时间是所有与它相连的并且已经遍历过的点的第三小的时间加1(这个要自己好好考虑,仔细读题)。然后把这个点设为已遍历!
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
const int N = 30;
const int INF = 0x3fffffff;
int n, m, g[N][N], d[N];
int ans, id;
char str[5];
bool vis[N];
map <char, int> mp;
queue<int> q;
bool cmp( int a, int b ) {
return a > b;
}
void BFS()
{
while ( !q.empty() ) {
int x = q.front(); q.pop();
for ( int i = 0; i < id; ++i ) if ( g[x][i] && !vis[i] ) {
int tt[N], cnt = 0;
for ( int v = 0; v < id; ++v ) if ( g[i][v] && vis[v] )
tt[cnt++] = d[v];
if ( cnt > 2 ) {
sort( tt, tt+cnt );
vis[i] = 1;
d[i] = tt[2] + 1;
q.push(i);
}
}
}
}
bool judge()
{
int flag = 0;;
for ( int i = 0; i < id; ++i ) {
//printf("%d ", d[i]);
if ( vis[i] ) flag++;
}
sort( d, d+id, cmp );
ans = d[0];
return flag == n;
}
int addpoint(char ch)
{
if ( !mp.count(ch) )
mp[ch] = id++;
return mp[ch];
}
void init()
{
mp.clear();
id = 0;
memset( g, 0, sizeof(g));
memset( vis, 0, sizeof(vis));
for ( int i = 0; i <= n; ++i ) d[i] = INF;
scanf("%s", str);
int len = strlen(str);
for ( int i = 0; i < len; ++i ) {
int u = addpoint(str[i]);
vis[u] = true;
d[u] = 0;
q.push(u);
}
while (m--) {
scanf("%s", str);
int u, v;
u = addpoint(str[0]);
v = addpoint(str[1]);
g[u][v] = g[v][u] = 1;
}
}
int main()
{
while ( scanf("%d", &n) != EOF ) {
scanf("%d", &m);
init();
BFS();
if ( judge() ) printf("WAKE UP IN, %d, YEARS\n", ans);
else printf("THIS BRAIN NEVER WAKES UP\n");
}
}