Problem Description
Consider a Depth-First-Search(DFS) spanning tree T of a undirected connected graph G, we define a T-Simple Circle as a path v1, v2, ..., vk (v1 = vk) in G that contains at most one edge which not belongs to the DFS spanning tree T.
Given a graph G, we process DFS on G starting from vertex 1 and get a DFS spanning tree T, then you should choose some edges of G so that all T-Simple Circles contains at least one edge that you choose.
Please minimize the number of edges you choose.
 
Input
There are at most 100 test cases.
For each case, the first line contains two integers n and m denoting the number of vertices and edges. The vertexes are numbered from 1 to n.
The following m lines describe the graph. Each line contains two integers xi and yi, denoting an edge between vertex xi and yi(xi ≠ yi).
Note that the first n-1 edges of input construct a DFS spanning tree T which is generated by DFS from vertex 1.
Input ends with n = 0 and m = 0
(1 <= n <= 2000, 1 <= m <= 20000, 1 <= xi, yi <= n)
 
Output
For each case, output the number of minimal edges that you choose.
 
PS:有个大于号写反了居然过了样例……样例不要这么坑爹好吗……
 
代码(812MS):
 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std; const int MAXN = ;
const int MAXE = ; int dep[MAXN]; struct Edge {
int x, y, id;
void read(int i) {
id = i;
scanf("%d%d", &x, &y);
}
void adjust() {
if(dep[x] > dep[y]) swap(x, y);
}
bool operator < (const Edge &rhs) const {
return dep[x] > dep[rhs.x];
}
} e[MAXE]; int n, m;
int head[MAXN], fa[MAXN];
int to[MAXN * ], next[MAXN * ];
int ecnt; void init() {
memset(head, , sizeof(head));
ecnt = ;
} void add_edge2(int u, int v) {
to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; next[ecnt] = head[v]; head[v] = ecnt++;
} void bfs() {
memset(dep, -, sizeof(dep));
queue<int> que; que.push();
dep[] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(dep[v] == -) {
fa[v] = u;
dep[v] = dep[u] + ;
que.push(v);
}
}
}
} bool vis[MAXN]; bool check(Edge &p) {
int now = p.y;
while(fa[now] != p.x) {
if(vis[now]) break;
now = fa[now];
}
if(!vis[now]) {
vis[now] = true;
return false;
}
else return true;
} int main() {
while(scanf("%d%d", &n, &m) != EOF) {
if(n == && m == ) break;
for(int i = ; i <= m; ++i) e[i].read(i);
init();
for(int i = ; i < n; ++i) add_edge2(e[i].x, e[i].y);
bfs();
for(int i = n; i <= m; ++i) e[i].adjust();
sort(e + , e + m + );
memset(vis, , sizeof(vis));
int ans = ;
for(int i = ; i <= m; ++i)
if(e[i].id >= n && !check(e[i])) ++ans;
printf("%d\n", ans);
}
}

HDU 4582 DFS spanning tree(DFS+贪心)(2013ACM-ICPC杭州赛区全国邀请赛)的更多相关文章

  1. HDU 4408 Minimum Spanning Tree 最小生成树计数

    Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  2. hdu 4408 Minimum Spanning Tree

    Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Krusk ...

  3. HDU 2489 Minimal Ratio Tree (dfs+Prim最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2489 Problem Description For a tree, which nodes and ...

  4. HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)

    Minimal Ratio Tree Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) ...

  5. [hdu4582]DFS spanning tree

    考虑每一条非树边都连接了祖先和儿子,类似于序列上的问题,从底往上算,当发现如果走到某个环的祖先,且这个环中还没有被选到,那么就将最浅的那条边贪心选择即可具体实现可以使用bitset维护当前子树的询问, ...

  6. HDU 2489 Minimal Ratio Tree(dfs枚举+最小生成树)

    想到枚举m个点,然后求最小生成树,ratio即为最小生成树的边权/总的点权.但是怎么枚举这m个点,实在不会.网上查了一下大牛们的解法,用dfs枚举,没想到dfs还有这么个作用. 参考链接:http:/ ...

  7. [2019杭电多校第四场][hdu6614]AND Minimum Spanning Tree(贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6614 题目大意是有一张n个点的完全图,n个点点权为1-n,边权为两点点权按位与(&).求最小生 ...

  8. HDU 4896 Minimal Spanning Tree(矩阵高速功率)

    意甲冠军: 给你一幅这样子生成的图,求最小生成树的边权和. 思路:对于i >= 6的点连回去的5条边,打表知907^53 mod 2333333 = 1,所以x的循环节长度为54,所以9个点为一 ...

  9. HDU 4573 Throw the Stones(动态三维凸包)(2013 ACM-ICPC长沙赛区全国邀请赛)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4573 Problem Description Remember our childhood? A fe ...

随机推荐

  1. 用c#语言编写1000以内能整除3的数字

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  2. Question 20171114 String的一些问题?

    欢迎各位大神提问题及补充不足和警醒错误! Question 20171113  Java中char为什么占用两个字节? Java是使用Unicode编码的所以Java会将源代码以Unicode的方式编 ...

  3. foreach, for in, for of 之间的异同

    forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数. 注意: forEach() 对于空数组是不会执行回调函数的. 示例代码: var arr = [4, 9, 16, 25]; ...

  4. C.Sum 2017 ACM-ICPC 亚洲区(西安赛区)网络赛

    题目来源:Sum 限制:1000ms 32768K Define the function S(x) for xx is a positive integer. S(x) equals to the ...

  5. spring boot 小案例

    1. SpringBoot 1.1. 概要 在传统的SSM框架应用过程中,存在大量的配置文件,及相关的配置项,例如: 1. DispatcherServlet 2. CharacterEncoding ...

  6. 快速创建显示数字数据的动画——CountUp.js

    由于项目需求,需要写一个数字增/减量的动画特效,最后找到了CountUp.js CountUp.js是一个无依赖,轻量级的JavaScript“类”,可用于快速创建以更有趣的方式显示数字数据的动画. ...

  7. vue路由回退判断

    在页面一开始加上一个全局的函数: activated: function () { this.$setgoindex() } 这个函数是这样的,判断当前页面的历史记录是不是小于等于1,如果小于等于1, ...

  8. Xshell6破解

    链接: https://pan.baidu.com/s/1P9kMmGdLfpPPxEgUxNXrhw 提取码: s3js

  9. 数据分析处理库Pandas——索引进阶

    Series结构 筛选数据 指定值 备注:查找出指定数值的索引和数值. 逻辑运算 备注:查找出值大于2的数据. 复合索引 DataFrame结构 显示指定列 筛选显示 备注:值小于0的显示原值,否则显 ...

  10. python三大神器之生成器

    生成器Generator: 本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现) 特点:惰性运算,开发者自定义 在python中有三种方法来获取生成器: 1.通过生成 ...