Rikka with Graph(hdu5631)
Rikka with Graph
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 给出一张 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条可以连通所有点的边,同时也判断了,整个图是否连通,然后剩下的2条边,分别以该边的一个点为起点
另一个位终点,用最短路搜连接这两个点的最小环由哪些边组成,然后记录个环的共同边ans,和两个环各自的边nk,mk,最后答案就是nk+mk-ans+nk*mk-ans*ans;nk+mk-ans--去掉一个边的方案,应为环去一边,所有点还是连通的。
nk*mk-ans*ans--去两个边的可能每个环出一个边方案为nk*mk,因为两个环重合的地方不能去,所以减ans*ans;
这个复杂度为(N*N)AC 0ms
1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string.h>
5 #include<queue>
6 #include<vector>
7 #include<set>
8 #include<map>
9 #include<math.h>
10 using namespace std;
11 struct node
12 {
13 int x;
14 int y;
15 };
16 vector<int>dian[110];
17 node bian[110];
18 bool flag[110];
19 int bin[110];
20 int shen[110];
21 int dj[110];
22 int TWO[200];
23 int HH[110];
24 int mapp[110][110];
25 int ma[110][110];
26 int pre[110];
27 int DD[110];
28 int CC[110];
29 map<int,int>my;
30 int cha(int x,int y);
31 void dfs(int n,int z);
32 void ME()
33 { int i,j;
34 memset(flag,0,sizeof(flag));
35 for(i=0; i<110; i++)
36 {
37 bin[i]=i;
38 shen[i]=1;
39 }
40 for(i=0; i<110; i++)
41 {
42 for(j=0; j<110; j++)
43 {
44 mapp[i][j]=200;
45 }
46 }
47 } void dis(int n,int k);
48 int main(void)
49 {
50 int i,j,k,p,q,n;
51 //freopen("data.in","r",stdin);
52 //freopen("wrong.out","w",stdout);
53 scanf("%d",&k);
54 while(k--)
55 {
56 ME();scanf("%d",&n);
57 int cnt=0;
58 for(i=0; i<=n; i++)
59 {
60 scanf("%d %d",&bian[i].x,&bian[i].y);
61 int s=cha(bian[i].x,bian[i].y);
62 if(s==1)
63 {
64 TWO[cnt++]=i;
65 }
66 }
67 for(i=1; i<=n; i++)
68 {
69 for(j=i; bin[j]!=j;)
70 j=bin[j];
71 HH[i]=j;
72 }
73 for(i=2; i<=n; i++)
74 {
75 if(HH[i]!=HH[1])
76 {
77 break;
78 }
79 }
80 if(i!=n+1)
81 {
82 printf("0\n");
83 }
84 else
85 {
86 int vx=bian[TWO[0]].x;
87 int vy=bian[TWO[0]].y;
88 int vxx=bian[TWO[1]].x;
89 int vyy=bian[TWO[1]].y;
90 for(i=0; i<=n; i++)
91 {
92 if(i!=TWO[0]&&i!=TWO[1])
93 {
94 mapp[bian[i].x][bian[i].y]=1;
95 mapp[bian[i].y][bian[i].x]=1;
96 ma[bian[i].x][bian[i].y]=i;
97 ma[bian[i].y][bian[i].x]=i;
98 }
99 }
100 dis(vxx,n);
101 int va=pre[vyy];int hh=vyy;
102 memset(DD,0,sizeof(DD));
103 while(va!=-1)
104 {
105 DD[va]=1;
106 int xx=bian[va].x;
107 int yy=bian[va].y;
108 if(hh!=xx)
109 {va=pre[xx];hh=xx;}
110 else {va=pre[yy];hh=yy;}
111
112 }
113 DD[TWO[1]]=1;
114 dis(vx,n);
115 va=pre[vy];hh=vy;
116 memset(CC,0,sizeof(CC));
117 while(va!=-1)
118 {
119 CC[va]=1;
120 int xx=bian[va].x;
121 int yy=bian[va].y;
122 if(hh!=xx)
123 {va=pre[xx];hh=xx;}
124 else {va=pre[yy];hh=yy;}
125
126 }
127 CC[TWO[0]]=1;
128 int ans=0;int nk=0;int mk=0;
129 for(i=0;i<=n;i++)
130 {
131 if(CC[i]&&DD[i])
132 {
133 ans++;
134 }
135 if(CC[i])
136 {
137 nk++;
138 }
139 if(DD[i])
140 {
141 mk++;
142 }
143 }
144 int sum=nk+mk-ans+nk*mk-ans*ans;
145 printf("%d\n",sum);
146 }}return 0; }
147 int cha(int x,int y)
148 {
149 int i,j;
150 int xx,yy;
151 for(xx=x; bin[xx]!=xx;)
152 xx=bin[xx];
153 for(yy=y; bin[yy]!=yy;)
154 yy=bin[yy];
155 if(xx==yy)
156 {
157 return 1;
158 }
159 if(xx!=yy)
160 {
161 if(shen[xx]>shen[yy])
162 {
163 shen[xx]+=shen[yy];
164 bin[yy]=xx;
165 }
166 else
167 {
168 shen[yy]+=shen[xx];
169 bin[xx]=yy;
170 }
171 }
172 return 0;
173 }
174 void dis(int n,int k)
175 {
176 fill(dj,dj+110,1000);
177 fill(pre,pre+110,-1);
178 dj[n]=0;int i,j;
179 memset(flag,0,sizeof(flag));
180 pre[n]=-1;
181 while(true)
182 {
183 int l=-1;
184 for(i=1; i<=k; i++)
185 {
186 if((l==-1||(dj[l]>dj[i]))&&!flag[i])
187 {
188 l=i;
189 }
190 }
191 if(l==-1)
192 {
193 break;
194 }
195 flag[l]=true;
196 for(i=1; i<=k; i++)
197 {
198 if(mapp[l][i]+dj[l]<dj[i])
199 {
200 pre[i]=ma[l][i];
201 dj[i]=mapp[l][i]+dj[l];
202 }
203 }
204 }
205 }
思路2:让 nn 个点联通最少需要 n-1n−1 条边,所以最多只能删除两条边,我们可以枚举删除的这两条边(或者唯一的一条边),然后并查集判断连通性就好了。时间复杂度 O(n^3)。
1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<stdlib.h>
5 #include<string.h>
6 #include<math.h>
7 #include<queue>
8 #include<stack>
9 #include<iomanip>
10 #include<cstdio>
11 #include<map>
12 #include<set>
13 #include <cmath>
14 #include <ctime>
15 #include <cstring>
16 #include <cctype>
17 #include <cassert>
18 #include<vector>
19 using namespace std;
20 struct node
21 {
22 int x;
23 int y;
24 };
25 node dian[200];
26 vector<int>vec[102];
27 bool flag[102];
28 bool flag1[103];
29 bool flag2[103];
30 int bincha[102];
31 int shendu[102];
32 int huanyuan[102];
33 int an=0;
34 void me()
35 {
36 memset(flag1,0,sizeof(flag));
37 memset(flag2,0,sizeof(flag1));
38 memset(flag,0,sizeof(flag));
39 int i,j;
40 for(i=0; i<102; i++)
41 {
42 bincha[i]=i;
43 shendu[i]=1;
44 }
45 }
46 void BB(int a,int b)
47 {
48 int x,y;
49 for(x=a; bincha[x]!=x;)
50 {
51 x=bincha[x];
52 }
53 for(y=b; bincha[y]!=y;)
54 {
55 y=bincha[y];
56 }
57 if(x!=y)
58 {
59 if(shendu[x]>shendu[y])
60 {
61 shendu[x]+=shendu[y];
62 bincha[y]=x;
63 }
64 else
65 {
66 shendu[y]+=shendu[x];
67 bincha[x]=y;
68 }
69 }
70 }
71 void slove (int s)
72 {
73 int i,j,k,m,n;
74 int fl=0;int nn,mm;
75 for(i=0; i<=s; i++)
76 {
77 for(j=i+1; j<=s; j++)
78 {
79 for(int z=0; z<102; z++)
80 {
81 bincha[z]=z;
82 shendu[z]=1;
83 }
84 for(m=0; m<=s; m++)
85 {
86 if(m!=i&&m!=j)
87 {
88 BB(dian[m].x,dian[m].y);
89 }
90 }
91 for(m=1;m<=s; m++)
92 {
93 for(n=m; bincha[n]!=n;)
94 n=bincha[n];
95 huanyuan[m]=n;
96 }
97 for(n=2; n<=s; n++)
98 {
99 if(huanyuan[n]!=huanyuan[1])
100 {
101 break;
102 }
103 }
104 if(n==s+1)
105 {
106 an++;
107 flag[i]=true;
108 flag[j]=true;
109
110 }
111 }
112 if(fl)
113 break;
114 }int ans[102];int cnt=0;
115 int bns[102];int cnt1=0;
116
117 }
118 int main(void)
119 {
120 int i,j,k,p,q;
121 int N; //freopen("data.in","r",stdin);
122 //freopen("wrong.out","w",stdout);
123 cin>>k;
124 while(k--)
125 { scanf("%d",&N) ;an=0;
126 for(i=0; i<102; i++)
127 vec[i].clear();
128 me();
129
130 for(i=0; i<N+1; i++)
131 {
132 cin>>p>>q;
133 dian[i].x=p;
134 dian[i].y=q;
135 vec[p].push_back(q);
136 vec[q].push_back(p);
137 BB(p,q);
138 }
139 for(i=1;i<=N;i++)
140 {
141 for(j=i;bincha[j]!=j;)
142 j=bincha[j];
143 huanyuan[i]=j;
144 }
145 for(i=2;i<=N;i++)
146 {
147 if(huanyuan[i]!=huanyuan[1])
148 {
149 break;
150 }
151 }
152 if(i!=N+1)
153 {
154 printf("0\n");
155 }
156 else
157 {
158 slove(N);
159 for(i=0;i<=N;i++)
160 {
161 if(flag[i])
162 {
163 an++;
164 }
165 }
166 printf("%d\n",an);
167 }
168
169 }
170 return 0;
171 }
N*N*N
Rikka with Graph(hdu5631)的更多相关文章
- HDU 5422 Rikka with Graph
Rikka with Graph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- Rikka with Graph(联通图取边,暴力)
Rikka with Graph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- HDU 6090 Rikka with Graph
Rikka with Graph 思路: 官方题解: 代码: #include<bits/stdc++.h> using namespace std; #define ll long lo ...
- HDU 5631 Rikka with Graph 暴力 并查集
Rikka with Graph 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5631 Description As we know, Rikka ...
- HDU 5424——Rikka with Graph II——————【哈密顿路径】
Rikka with Graph II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- HDU 6090 Rikka with Graph —— 2017 Multi-University Training 5
Rikka with Graph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- hdu 5424 Rikka with Graph II(dfs+哈密顿路径)
Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so h ...
- hdu 5422 Rikka with Graph(简单题)
Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...
- HDU 6090 17多校5 Rikka with Graph(思维简单题)
Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...
随机推荐
- java Random()用法
1.random.nextInt() random.nextIn()的作用是随机生成一个int类型,因为int 的取值范围是 -2147483648--2147483647 ,所以生成的数也是处于这个 ...
- 【每天五分钟大数据-第一期】 伪分布式+Hadoopstreaming
说在前面 之前一段时间想着把 LeetCode 每个专题完结之后,就开始着手大数据和算法的内容. 想来想去,还是应该穿插着一起做起来. 毕竟,如果只写一类的话,如果遇到其他方面,一定会遗漏一些重要的点 ...
- ps精修
1.磨皮方法: a,, 添加高斯模糊后,按住alt键新建图层蒙版,设置前景色为白色,用画笔在脸上雀斑的位置涂抹,注意脸轮廓位置不要涂抹.最后添加曲线提亮 b. 添加蒙尘和划痕后,后面上面的一样
- [项目总结]Android 手动显示和隐藏软键盘
1.方法一(如果输入法在窗口上已经显示,则隐藏,反之则显示) 1 InputMethodManager imm = (InputMethodManager) getSystemService(Cont ...
- 【Linux】【Shell】【Basic】一行代码解决常见问题
1. 查看可用IP for i in `seq 1 255`; do ping -c 1 10.210.55.$i >> /dev/null; if [ $? -eq 1 ]; then ...
- Druid数据库监控
一.简介 Druid是阿里开源的一个JDBC应用组件, 其包括三部分: DruidDriver: 代理Driver,能够提供基于Filter-Chain模式的插件体系. DruidDataSource ...
- contrller层的编码设设计流程以及详细配置
/** 实际开发中遵循一个规律:自己写的类使用注解,系统提供的类使用配置文件 1.书写controller类----->配置springmvc.xml-------->配置web ...
- IT过来人的10点经验谈
1 入行要趁早,正常是22岁本科或25岁硕士毕业入行.如果是零基础经培训班加持的,尽量在28岁前入行,30岁以后再想要入行IT的,千万慎重. 2 IT行业确实能挣大钱,而且能为学历一般学校一般家庭背景 ...
- shell脚本 批量查看mysql表条目数
一.简介 源码地址 日期:2018/4/12 介绍:查看mysql的信息,用于比对和查询条目数 效果图: 二.使用 适用:centos6+ 语言:中文 注意:适用于5.7版本,其它版本要更改变量han ...
- 嵌入式实验一:LED灯点亮
实验一:LED灯程序 一. 实验环境 开发机环境 操作系统:ubuntu 12.04 交叉编译环境:arm-linux-gcc 4.3.2 6410板子内核源码:linux-3.0.1 目 ...