Light OJ 1308 - Ant Network
来源:互联网 发布:阿里云机顶盒 编辑:程序博客网 时间:2024/06/04 01:28
题意:
给一个无向图,每个点都有蚂蚁,一旦摧毁掉某个点后,所有点上的蚂蚁必须都能跑到庇护所,问最少需要在多少个上安排庇护所使得,任意一个点摧毁后,所有蚂蚁都是安全的?
思路:
首先如果给定的图为一个连通块的话,那么至少需要2个点。
接下来就求一下图内的割点。
对于一个联通块内,如果有多于一个割点的话,这样是不需要放置庇护点的,因为只能摧毁掉一个点,我可以选择其他一个割点去庇护所。否则这个联通块内就需要放置庇护所了。
代码:
#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <iostream>#include <cmath>#include <map>#include <vector>#include <set>#include <string>#define PB push_back#define FT first#define SD second#define MP make_pair#define INF 0x3f3f3f3fusing namespace std;typedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> P;const int N = 5 + 1e4,M = 7+1e9;int n, m;int tot, head[N], resCut;int top, ord, DFN[N], low[N], st[N];bool instack[N], isCut[N];struct edge{ int to,next;}e[4*N];void init(){ tot = ord = top = resCut = 0; memset(head, -1, sizeof(head)); memset(DFN, -1, sizeof(DFN)); memset(low, -1, sizeof(low)); memset(instack, 0, sizeof(instack)); memset(isCut, 0, sizeof(isCut));}void addedge(int u,int v){ e[tot].to = v, e[tot].next = head[u], head[u] = tot++;}void tarjan(int u, int fa){ DFN[u] = low[u] = ord ++; instack[u] = 1; st[top++] = u; int child = 0; for(int i = head[u];i != -1;i = e[i].next) { int v = e[i].to; if(v == fa) continue; if(DFN[v] == -1){ child ++; tarjan(v,u); if(low[u] > low[v]){ low[u] = low[v]; } if(fa == -1 && child > 1) isCut[u] = 1; if(fa != -1 && low[v] >= DFN[u]) isCut[u] = 1; resCut += isCut[u]; } else if(instack[v]) { low[u] = min(low[u], DFN[v]); } }}set<int> ss;bool vis[N];int cnt;void dfs(int u){ vis[u] = 1; cnt ++; for(int i = head[u];i != -1;i = e[i].next) { int v = e[i].to; if(isCut[v]) { ss.insert(v); continue; } if(isCut[v] || vis[v]) continue; dfs(v); }}int main(){ int T, u, v, ca = 0; scanf("%d",&T); while(T --){ scanf("%d%d",&n,&m); init(); while(m --){ scanf("%d%d",&u,&v); addedge(u,v), addedge(v,u); } tarjan(0,-1); int ans1 = 0; ULL ans2 = 1; if(resCut == 0) { ans1 = 2, ans2 = 1ULL * n * (n - 1) / 2; } else { memset(vis, 0, sizeof(vis)); for(int i = 0;i < n;i ++) { if(isCut[i] || vis[i]) continue; ss.clear(); cnt = 0; dfs(i); if(ss.size() <= 1) { ans1 ++, ans2 *= cnt; } } } printf("Case %d: %d %llu\n", ++ca, ans1, ans2); } return 0;}
0 0
- Light OJ 1308 - Ant Network
- light oj
- light oj
- Light OJ
- Light OJ
- Light OJ 1000
- Light OJ 1001
- Light OJ 1008
- Light OJ 1022
- Light OJ 1015
- Light OJ 1042
- light oj 1128
- Light OJ 1055 BFS
- Light OJ Beginners Problems
- Light OJ Basic Geometry
- Light OJ Basic Math
- light oj 1124
- Light OJ 1012
- java判断字符串是否为空的方法总结
- ios-复制字符串到剪贴板
- js 导出excel
- iOS常用加密方法(aes、md5、base64)
- 升级到xcode7之后ipa文件尺寸增大,strip无效问题
- Light OJ 1308 - Ant Network
- Http协议详解
- 对于linux下system()函数的深度理解(整理)
- leetcode -- Largest Rectangle in Histogram -- 重点,多看几遍
- Android刷linux系统
- 脸上长痘部位详解 从痘痘看身体状况
- Mean Shift 均值漂移聚类
- SHH数据结构-【实训-银行业务的模拟系统 】
- <iOS>Git基础