题目链接:http://codeforces.com/problemset/problem/131/D

思路: 题目的意思是说给定一个无向图,求图中的顶点到环上顶点的最短距离(有且仅有一个环,并且环上顶点的距离不计)。

一开始我是直接用Tarjan求的无向图的双连通分量,然后标记连通分量上的点(如果某一个连通分量上的顶点的个数大于1,那么就是环了,其余的都只有一个点),然后即使重新建图,spfa求最短路径。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std; const int MAX_N = (3000 + 300);
int dfn[MAX_N], low[MAX_N], cnt, N, _count, color[MAX_N];
int st, dist[MAX_N];
bool mark[MAX_N];
vector<int > g[MAX_N], reg[MAX_N];
stack<int > S; void Tarjan(int u, int father)
{
low[u] = dfn[u] = ++cnt;
S.push(u);
mark[u] = true;
REP(i, 0, (int)g[u].size()) {
int v = g[u][i];
if (father == v) continue;
if (dfn[v] == 0) {
Tarjan(v, u);
low[u] = min(low[u], low[v]);
} else if (mark[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if (low[u] == dfn[u]) {
int x, num = 0;
++_count;
do {
x = S.top();
S.pop();
mark[x] = false;
color[x] = _count;
++num;
} while (x != u);
if (num > 1) st = _count;
}
} void spfa(int st)
{
queue<int > que;
memset(dist, 0x3f, sizeof(dist));
memset(mark, false, sizeof(mark));
dist[st] = 0;
que.push(st);
while (!que.empty()) {
int u = que.front();
que.pop();
REP(i, 0, (int)reg[u].size()) {
int v = reg[u][i];
if (dist[u] + 1 < dist[v]) {
dist[v] = dist[u] + 1;
if (!mark[v]) {
mark[v] = true; que.push(v);
}
}
}
}
} int main()
{
while (cin >> N) {
FOR(i, 1, N) g[i].clear(), reg[i].clear();
FOR(i, 1, N) {
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
cnt = _count = 0;
memset(dfn, 0, sizeof(dfn));
memset(mark, false, sizeof(mark));
FOR(i, 1, N) if (!dfn[i]) Tarjan(i, -1);
FOR(u, 1, N) {
REP(i, 0, (int)g[u].size()) {
int v = g[u][i];
if (color[u] != color[v]) reg[color[u]].push_back(color[v]), reg[color[v]].push_back(color[u]);
}
}
spfa(st);
FOR(i, 1, N) {
cout << dist[color[i]];
if (i == N) cout << endl;
else cout << " ";
}
}
return 0;
}

后来我发现自己想的太复杂了,其实只要一遍dfs就能求出这个环上的点了,具体的做法是从某一点开始深搜,然后如果遇上之前搜过的点,那么说明形成一个环,用一个变量记录这个点,然后回退的时候判断是否遇到过这个点,如果没有遇到过,就把回退路径上的点都标记为环上的点,否则,继续回退。最后即使一遍bfs就可以求出最短路径。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std; const int MAX_N = (3000 + 300);
int N, flag[MAX_N], dist[MAX_N], mark[MAX_N], found, st, Ok;
vector<int > g[MAX_N]; void dfs(int u, int father)
{
mark[u] = true;
REP(i, 0, (int)g[u].size()) {
int v = g[u][i];
if (v == father) continue;
if (!mark[v]) dfs(v, u);
else { found = 1; st = v; flag[u] = 1; return; } if (found) {
if (Ok) return;
if (st == u) Ok = 1;
flag[u] = 1;
return;
}
}
} void bfs(int st)
{
queue<int > que;
memset(mark, false, sizeof(mark));
mark[st] = true;
dist[st] = 0;
que.push(st);
while (!que.empty()) {
int u = que.front();
que.pop();
REP(i, 0, (int)g[u].size()) {
int v = g[u][i];
if (mark[v]) continue;
mark[v] = true;
if (flag[v]) dist[v] = 0;
else dist[v] = dist[u] + 1;
que.push(v);
}
}
} int main()
{
while (cin >> N) {
FOR(i, 1, N) g[i].clear(), flag[i] = mark[i] = 0;
FOR(i, 1, N) {
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
found = Ok = 0;
dfs(1, 1);
bfs(st);
FOR(i, 1, N) {
cout << dist[i];
if (i == N) cout << endl;
else cout << " ";
}
}
return 0;
}

Codeforces Beta Round #95 (Div. 2) D.Subway的更多相关文章

  1. Codeforces Beta Round #95 (Div. 2) D. Subway dfs+bfs

    D. Subway A subway scheme, classic for all Berland cities is represented by a set of n stations conn ...

  2. Codeforces Beta Round #95 (Div. 2) D. Subway 边双联通+spfa

    D. Subway   A subway scheme, classic for all Berland cities is represented by a set of n stations co ...

  3. codeforces水题100道 第二十六题 Codeforces Beta Round #95 (Div. 2) A. cAPS lOCK (strings)

    题目链接:http://www.codeforces.com/problemset/problem/131/A题意:字符串大小写转换.C++代码: #include <cstdio> #i ...

  4. Codeforces Beta Round #95 (Div. 2) C. The World is a Theatre 组合数学

    C. The World is a Theatre There are n boys and m girls attending a theatre club. To set a play " ...

  5. Codeforces Beta Round #95 (Div. 2) C 组合数学

    C. The World is a Theatre time limit per test 2 seconds memory limit per test 256 megabytes input st ...

  6. Codeforces Beta Round #80 (Div. 2 Only)【ABCD】

    Codeforces Beta Round #80 (Div. 2 Only) A Blackjack1 题意 一共52张扑克,A代表1或者11,2-10表示自己的数字,其他都表示10 现在你已经有一 ...

  7. Codeforces Beta Round #83 (Div. 1 Only)题解【ABCD】

    Codeforces Beta Round #83 (Div. 1 Only) A. Dorm Water Supply 题意 给你一个n点m边的图,保证每个点的入度和出度最多为1 如果这个点入度为0 ...

  8. Codeforces Beta Round #79 (Div. 2 Only)

    Codeforces Beta Round #79 (Div. 2 Only) http://codeforces.com/contest/102 A #include<bits/stdc++. ...

  9. Codeforces Beta Round #77 (Div. 2 Only)

    Codeforces Beta Round #77 (Div. 2 Only) http://codeforces.com/contest/96 A #include<bits/stdc++.h ...

随机推荐

  1. 【leetcode】First Missing Positive

    First Missing Positive Given an unsorted integer array, find the first missing positive integer. For ...

  2. Wince下sqlce数据库开发(二)

    上次写到使用数据绑定的方法测试本地sqlce数据库,这次使用访问SQL Server的方法访问sqlce,你会发现他们是如此的相似... 参考资料:http://www.cnblogs.com/rai ...

  3. RecyclerView notifyDataSetChanged不起作用

    一般listview设置完data后调用notifyDataSetChanged便可刷新布局界面,然而recycleview调用这个方法却没有任何反应.对于很多不熟悉recycleview的话很容易躺 ...

  4. zju3430

    题意:给出多个加密的模式串,和多个待匹配的串,问每个串里出现了多少种模式串.加密方法是把每3bytes加密成按6bits一个对应成4个字符,对应方法题里给了. 分析:除了解密之外,基本是个赤裸裸的AC ...

  5. MongoDB 分片的原理、搭建、应用

    一.概念: 分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载.基本思想就是将集合切成小块,这 ...

  6. Pooled Allocation(池式分配)实例——Keil 内存管理

    引言:说到动态申请(Dynamic Allocation)内存的好处,学过C/C++的人可能都有体会.运行时的灵活申请自然要比编码时的猜测好的多.而在内存受限情况下这种灵活性又有特别的好处--能让我们 ...

  7. 迷宫问题_BFS_挑战程序设计竞赛p34

    给定一个N*M的迷宫,求从起点到终点的最小步数. N,M<100: 输入: 10 10#S######.#......#..#.#.##.##.#.#........##.##.####.... ...

  8. nyoj1000_快速幂_费马小定理

    又见斐波那契数列 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 斐波那契数列大家应该很熟悉了吧.下面给大家引入一种新的斐波那契数列:M斐波那契数列. M斐波那契数列 ...

  9. jQueryUI Datepicker的使用

    jQueryUI Datepicker是一个高度可定制的插件,可以很方便的为你的页面添加日期选择功能,你可以自定义日期的显示格式 以及要使用的语言. 你可以使用键盘的快捷键来驱动datepicker插 ...

  10. Spring+SpringMVC+Mybatis 多数据源整合(转)

    转载自:http://blog.csdn.net/q908555281/article/details/50316137 目录(?)[-]拷贝所需jar拷贝jar文件需要的jar文件入下图所示因为我的 ...