Rikka with Graph

 Accepts: 123
 Submissions: 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条可以连通所有点的边,同时也判断了,整个图是否连通,然后剩下的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)的更多相关文章

  1. HDU 5422 Rikka with Graph

    Rikka with Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  2. Rikka with Graph(联通图取边,暴力)

    Rikka with Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  3. HDU 6090 Rikka with Graph

    Rikka with Graph 思路: 官方题解: 代码: #include<bits/stdc++.h> using namespace std; #define ll long lo ...

  4. HDU 5631 Rikka with Graph 暴力 并查集

    Rikka with Graph 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5631 Description As we know, Rikka ...

  5. HDU 5424——Rikka with Graph II——————【哈密顿路径】

    Rikka with Graph II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  6. 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) ...

  7. 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 ...

  8. hdu 5422 Rikka with Graph(简单题)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  9. 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 ...

随机推荐

  1. lua_newthread的真正意义

    lua_newthread 这个接口,存在误导性,很多人第一次试图用它来解决多线程问题时,都会入坑. 实际上,这个接口真正的用法,是给那些在lua更底层的某些行为(通常是递归)导致了lua的栈溢出而准 ...

  2. 33、搜索旋转排序数组 | 算法(leetode,附思维导图 + 全部解法)300题

    零 标题:算法(leetode,附思维导图 + 全部解法)300题之(33)搜索旋转排序数组 一 题目描述! 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: // 方案1 & ...

  3. 工作学习1-tcp自连接

    运维同事反馈服务起不来.下面为了方便,写了一个demo来展示. https://gitee.com/northeast_coder/code/tree/master/case/case1_tcp_se ...

  4. 第三个基础框架 — springMVC — 更新完毕

    1.什么是springMVC? 还是老规矩,百度百科一下 这里面说了一堆废话,去官网瞄一下 官网网址:https://docs.spring.io/spring-framework/docs/curr ...

  5. 学习java的第二十七天

    一.今日收获 1.java完全学习手册第三章算法的3.2排序,比较了跟c语言排序上的不同 2.观看哔哩哔哩上的教学视频 二.今日问题 1.快速排序法的运行调试多次 2.哔哩哔哩教学视频的一些术语不太理 ...

  6. 日常Java 2021/10/12

    封装 在面向对象程式设计方法中,封装是指-种将抽象性函式接口的实现细节部分包装.隐藏起来的方法 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问 要访问该类的代码和数据,必 ...

  7. A Child's History of England.26

    CHAPTER 9 ENGLAND UNDER WILLIAM THE SECOND, CALLED RUFUS William the Red, in breathless haste, secur ...

  8. python格式化输出的两种方式对比

    1.%符号方法和format()函数方法 2.对比: 1 print('我今年%d岁' %22.125) 2 print('我今年{0:f}'.format(22.125)) 3 #报错 4 #槽中类 ...

  9. 面试一定会问到的-js事件循环

    这篇文章讲讲浏览器的事件循环(nodejs中的事件循环稍有不同),事件循环是js的核心之一,因为js是单线程,所以异步事件实现就是依赖于事件循环机制,理解事件循环可让我们更清晰的处理js异步事件和应对 ...

  10. Linux学习 - 数值运算

    1 declare 声明变量类型 declare [+/-] [选项] 变量名 - 给变量设定类型属性 + 取消变量的类型属性 -i 将变量声明为整数型 -x 将变量声明为环境变量(同export) ...