BestCoder Round #73 (div.2)(B)并查集
2016-02-20 22:10
513 查看
Rikka with Graph
Accepts: 123Submissions: 525
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 给出一张 nn 个点 n+1n+1 条边的无向图,你可以选择一些边(至少一条)删除。 现在勇太想知道有多少种方案使得删除之后图依然联通。 当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
第一行一个整数表示数据组数 T(T \leq 30)T(T≤30)。 每组数据的第一行是一个整数 n(n \leq 100)n(n≤100)。 接下来 n+1n+1 行每行两个整数 u,vu,v 表示图中的一条边。
输出描述
对每组数据输出一行一个整数表示答案。
输入样例
1 3 1 2 2 3 3 1 1 3
输出样例
9
题解:他只给你(N+1)条边,而形成一个联通图至少需要(N-1)条边,那么多出来的2条边只需要双重循环枚举删除2条边的各种可能性就好了,使用并查集维护点的关系,这里如果出现多棵树的根,那么就一定不是联通图,这里还是说一下,枚举从自己开始枚举,就是删除一条边的情况与删除2条边的情况
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<utility> using namespace std; vector<pair<int,int>>v; #define N 105 int fa ; int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } void unio(int x,int y) { x=find(x); y=find(y); if(x!=y) fa[x]=y; } int solve(int x,int y,int n) { for(int i=1;i<=n;i++) { fa[i]=i; } for(int i=0;i<=n;i++) { if(i==x||i==y) continue; unio(v[i].first,v[i].second); } int num=0; for(int i=1;i<=n;i++) { if(fa[i]==i) num++; } return num>1?0:1; } int main() { #ifdef CDZSC freopen("i.txt","r",stdin); #endif int n,y,x,t; scanf("%d",&t); while(t--) { int ans=0; v.clear(); scanf("%d",&n); for(int i=0;i<=n;i++) { scanf("%d%d",&x,&y); v.push_back(make_pair(x,y)); } for(int i=0;i<=n;i++) { for(int j=i;j<=n;j++) { ans+=solve(i,j,n); } } printf("%d\n",ans); } return 0; }
相关文章推荐
- Java [Leetcode 278]First Bad Version
- 韬晦术
- 构筑测试体系
- jquery easyui添加图标扩展
- OpenJudge百炼习题解答(C++)--题1936:全在其中
- C#里氏转换/is/as
- UVA_11090_GoingInCycle!!
- 关于async和await的一些误区实例详解
- 费用流解决最优匹配 PKU3686
- Markdown 编辑器集锦
- iOS-真机调试
- Java基础理解
- Android更改桌面应用程序launcher的两种方式
- LinkageError
- win 7 取得最高权限
- bzoj1006: [HNOI2008]神奇的国度
- hdoj 2033 人见人爱
- BestCoder Round #73 (div.2) (A)思维
- js正则表达式语法
- swift语法(二)