BC73 div2 Rikka with Graph 删除边,最多能生成几棵树 HDU 5631
2016-02-21 16:48
483 查看
Rikka with Graph
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 308 Accepted Submission(s): 147
Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:
Yuta has a non-direct graph with n vertices and n+1 edges. Rikka can choose some of the edges (at least one) and delete them from the graph.
Yuta wants to know the number of the ways to choose the edges in order to make the remaining graph connected.
It is too difficult for Rikka. Can you help her?
Input
The first line contains a number T(T≤30)——The
number of the testcases.
For each testcase, the first line contains a number n(n≤100).
Then n+1 lines follow. Each line contains two numbers u,v ,
which means there is an edge between u and v.
Output
For each testcase, print a single number.
Sample Input
1 3 1 2 2 3 3 1 1 3
Sample Output
9
题目大意:
n个地点,n+1条路,每次删除其中几条边,但是这些地点仍然连接着。问,删除的方法有几种(删除一条或者一条以上)
n - 1 为生成了一棵树的依据,所以最多只能删除两条边
枚举,每次重连即可。最大为O(n^3)。
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<string> using namespace std; const int maxn = 300 + 10; struct edge{ int u, v; }; int n; edge ed[maxn]; int par[maxn], level[maxn]; int find(int x){ if (par[x] == x) return x; return par[x] = find(par[x]); } bool unite(int x, int y){ x = find(x); y = find(y); if (x == y) return false; if (level[x] > level[y]){ par[y] = x; } else { par[x] = y; if (level[x] == level[y]) level[x]++; } return true; } void init(){ for (int i = 0; i < n + 1; i++){ par[i] = i; level[i] = 0; } } void solve(){ int cnt = 0, tmp; for (int i = 0; i < n + 1; i++){ for (int j = i; j < n + 1; j++){ init(); tmp = 0; for (int k = 0; k < n + 1; k++){ if (k != i && k != j){ int flag = unite(ed[k].u, ed[k].v); if (flag == 1) tmp++; // printf("tmp = %d\n", tmp); } } // printf("\n"); if (tmp == n - 1){ cnt ++; } } } printf("%d\n", cnt); } int main(){ int t; scanf("%d", &t); while(t--){ scanf("%d", &n); for (int i = 0; i < n + 1; i++){ scanf("%d%d", &ed[i].u, &ed[i].v); } solve(); } return 0; } </string></queue></cstring></algorithm></cstdio>
相关文章推荐
- jQuery Validate验证框架详解
- php课程---简单的分页练习
- 【C语言项目】注释转换
- 大型网站技术架构读书笔记03—大型网站架构核心要素
- Redis性能测试
- 后端开发实践之路(二)--分布式系统和分布式理论
- 浅析 mondrian 模式文件 Schema
- Gym100496H-House of Representatives-树
- MEMS 陀螺仪资料整理之《MEMS 陀螺仪简介及其应用》
- Convert Sorted List to Binary Search Tree
- BZOJ1370Gang团伙
- 自己整理_银行核心系统相关技术知识
- 【慕课笔记】第三章 JAVA中必须了解的常用类 第6节 使用Math类操作数据
- 【转】Finding Windows CE bugs with help from "Dr. Watson"
- web页面滚动条样式修改
- XAMPP FOR PHPSTORM
- 移动端手指滑动切换图片框架
- VC2012 ActiveX 控制台打印调试
- android - Universal-Image-Loader,android-Volley,Picasso、Fresco和Glide五大Android开源组件加载图片的优缺点比较
- Linux 常用命令集合