ACM预备队-week5(DFS/BFS/二分图)
[蓝桥杯 2013 国 C] 危险系数
题目链接:P8604 [蓝桥杯 2013 国 C] 危险系数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
割点:
删除这个顶点集合以所有顶点相关联的边以后,图的连通分量增多
其实就是求图的割点,找到“关键枢纽”,因为是稀疏图,所以用邻接表存图。
遍历起点->终点的所有路径(DFS),在遍历过程中,如果可以到达终点,则给中途经过的点的标记+1,找到从起点到终点路径数目相同的点(除去起点和终点),该数目即为ans
1 #include <bits/stdc++.h>
2 #define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
3 using namespace std;
4 const int N=2010;
5 int n,m;
6 bool vis[N];
7 int st,ed;
8 int tot;//表示起点到终点的路径数
9 int cnt[N];
10 int ans;
11 int h[N],e[N],ne[N],idx;
12 void add(int a,int b)
13 {
14 e[idx]=b,ne[idx]=h[a],h[a]=idx++;
15 }
16 void dfs(int u)
17 {
18 vis[u]=true;
19 if(u==ed)
20 {
21 tot++;
22 for(int i=1;i<=n;i++)
23 {
24 if(vis[i])cnt[i]++;
25 }
26 return;
27 }
28 for(int i=h[u];i!=-1;i=ne[i])
29 {
30 int j=e[i];
31 if(!vis[j])
32 {
33 dfs(j);
34 vis[j]=0;
35 }
36 }
37 return;
38
39 }
40 int main()
41 {
42 io;
43 cin>>n>>m;
44 memset(h,-1,sizeof h);
45 for(int i=0;i<m;i++)
46 {
47 int a,b;
48 cin>>a>>b;
49 add(a,b),add(b,a);
50 }
51 cin>>st>>ed;
52 dfs(st);
53 for(int i=1;i<=n;i++)
54 {
55 if(cnt[i]==tot)ans++;
56 }
57 ans-=2;
58 cout<<ans;
59 return 0;
60 }
图的遍历
题目链接:P3916 图的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
稀疏图邻接表存图,反向真妙我真傻,从大到小遍历,经过的直接赋值最大点,O(n)复杂度,要不然1e5(⊙﹏⊙),基本正向就挂了
反向建图+DFS,不会缩点qwq
1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N=1e5+10;
4 int e[N],ne[N],idx,h[N];
5 bool st[N];
6
7 int ans[N];//用来存储答案
8 void add(int a,int b)//表示在a后加入b这个点
9 {
10 e[idx]=b,ne[idx]=h[a],h[a]=idx++;
11 }
12 void dfs(int u,int a)//对u这个节点赋值a
13 {
14 ans[u]=a;
15 st[u]=true;
16 for(int i=h[u];i!=-1;i=ne[i])
17 {
18 int j=e[i];
19 if(!st[j])dfs(j,a);
20 }
21 }
22 int main()
23 {
24 memset(h,-1,sizeof h);
25 int n,m;
26 cin>>n>>m;
27 for(int i=0;i<m;i++)
28 {
29 int a,b;
30 cin>>a>>b;
31 add(b,a);//反向建图
32 }
33 for(int i=n;i>=1;i--)
34 {
35 if(!st[i])dfs(i,i);
36 }
37 for(int i=1;i<=n;i++)
38 cout<<ans[i]<<' ';
39 }
【福建省历届夏令营】阳光大学
题目链接:P1330 封锁阳光大学 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
二分图,其实就是想把相邻的两个点染成不同的颜色,在每个连通块中加上两个颜色数目最小的点的数量,最后即为我要堵的答案
1 #include <bits/stdc++.h>
2 #define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
3 using namespace std;
4 const int N=1e5+10;
5 int n,m;
6 int h[N],e[N],ne[N],idx;
7 void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
8 int cnt[3];//表示1和2的二分子连通图各自的数量
9 int color[N];
10 bool dfs(int u,int c)//节点是u,c表示颜色
11 {
12 color[u]=c;
13 cnt[c]++;
14 for(int i=h[u];i!=-1;i=ne[i])
15 {
16 int j=e[i];
17 if(!color[j])//如果j这个点还没被染色
18 {
19 if(!dfs(j,3-c))return false;//如果接下来染色失败
20 }
21 else if(color[j]==c)return false;//如果染过色了,但是是冲突的
22 }
23 return true;
24 }
25 signed main()
26 {
27 io;
28 cin>>n>>m;
29 memset(h,-1,sizeof h);
30 while(m--){int a,b;cin>>a>>b;add(a,b);add(b,a);}
31 int ans=0;
32 for(int i=1;i<=n;i++)
33 {
34 cnt[1]=0,cnt[2]=0;
35 if(!color[i])
36 {
37 if(!dfs(i,1)){cout<<"Impossible";return 0;}//没有被染色并且染色后还矛盾了
38 }
39 ans+=min(cnt[1],cnt[2]);
40 }
41 cout<<ans;
42 return 0;
43 }
你本无意穿堂风,偏偏孤倨引山洪。
本文作者:Zac-saodiseng
本文链接:https://www.cnblogs.com/Zac-saodiseng/p/16927263.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步