链接:
http://poj.org/problem?id=3713
题意:
给出一个无向图(可能不联通),判断是否每两个点之间都能至少有3条独立不同的路径可达。独立定义为任意两条路径只有起点和
终点相同,其他点均不相同。
思路:
图的三联通判断。枚举删去一个点看是否存在割点,如果存在那么说明不满足。
代码:
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <queue> 5 #include <stack> 6 #include <cstdio> 7 #include <string> 8 #include <vector> 9 #include <cstdlib> 10 #include <cstring> 11 #include <sstream> 12 #include <iostream> 13 #include <algorithm> 14 #include <functional> 15 using namespace std; 16 #define rep(i,a,n) for (int i=a;i<n;i++) 17 #define per(i,a,n) for (int i=n-1;i>=a;i--) 18 #define all(x) (x).begin(),(x).end() 19 #define pb push_back 20 #define mp make_pair 21 #define lson l,m,rt<<1 22 #define rson m+1,r,rt<<1|1 23 typedef long long ll; 24 typedef vector<int> VI; 25 typedef pair<int, int> PII; 26 const ll MOD = 1e9 + 7; 27 const int INF = 0x3f3f3f3f; 28 const int MAXN = 2e4 + 7; 29 // head 30 31 int n, m, order = 0; 32 int low[MAXN], dfn[MAXN]; 33 int par[MAXN], son[MAXN]; 34 int vis[MAXN]; 35 VI G[MAXN]; 36 VI cutpoint; 37 vector<PII> cutedge; 38 int fg; 39 40 void tarjan(int u) { 41 if (fg) return; 42 vis[u] = 1; 43 dfn[u] = low[u] = ++order; 44 bool flag = false; 45 rep(i, 0, G[u].size()) { 46 int v = G[u][i]; 47 if (vis[v] == 2) continue; 48 if (!dfn[v]) { 49 son[u]++; 50 par[v] = u; 51 tarjan(v); 52 if (low[v] >= dfn[u]) flag = true; 53 low[u] = min(low[u], low[v]); 54 } 55 else if (v != par[u]) low[u] = min(low[u], dfn[v]); 56 } 57 if ((par[u] == -1 && son[u] > 1) || (par[u] != -1 && flag)) fg = 1; 58 } 59 60 void init() { 61 order = 0; 62 memset(low, 0, sizeof(low)); 63 memset(dfn, 0, sizeof(dfn)); 64 memset(par, 0, sizeof(par)); 65 memset(son, 0, sizeof(son)); 66 memset(vis, 0, sizeof(vis)); 67 } 68 69 int main() 70 { 71 while (cin >> n >> m, n) { 72 rep(i, 0, MAXN) G[i].clear(); 73 while (m--) { 74 int a, b; 75 scanf("%d%d", &a, &b); 76 G[a].pb(b); 77 G[b].pb(a); 78 } 79 fg = 0; 80 rep(k, 0, n) { 81 init(); 82 vis[k] = 2; 83 int root = k ? 0 : 1; 84 par[root] = -1; 85 tarjan(root); 86 rep(i, 0, n) if (!vis[i]) { 87 fg = 1; 88 break; 89 } 90 if (fg) break; 91 } 92 if (fg) cout << "NO" << endl; 93 else cout << "YES" << endl; 94 } 95 return 0; 96 }