1. 程式人生 > >[HDOJ6165] FFF at Valentine(強聯通分量,縮點,拓撲排序)

[HDOJ6165] FFF at Valentine(強聯通分量,縮點,拓撲排序)

har 之間 i++ name head cnblogs span fire --

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6165

題意:問一個有向圖中是否有任意兩點可以到達。

讀錯題就徹底輸了,讀成判斷是否有任意條路,使得經過所有點並且每條邊最多走一次。

強聯通縮點,然後維護拓撲序,假如拓撲序中有兩個以上點入度為0,那麽這幾個點之間就不能互相到達了。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 namespace fastIO {
  5     #define BUF_SIZE 20
  6     bool IOerror = 0;
7 inline char nc() { 8 static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE; 9 if (p1 == pend) { 10 p1 = buf; 11 pend = buf + fread(buf, 1, BUF_SIZE, stdin); 12 if (pend == p1) { 13 IOerror = 1; 14 return
-1; 15 } 16 } 17 return *p1++; 18 } 19 inline bool blank(char ch) { 20 return ch == || ch == \n || ch == \r || ch == \t; 21 } 22 inline void read(int &x) { 23 char ch; 24 while (blank(ch = nc())); 25 if
(IOerror) 26 return; 27 for (x = ch - 0; (ch = nc()) >= 0 && ch <= 9; x = x * 10 + ch - 0); 28 } 29 #undef BUF_SIZE 30 }; 31 32 const int maxn = 1010; 33 const int maxm = 6060; 34 typedef struct Edge { 35 int u, v, next; 36 Edge() { next = -1; } 37 }Edge; 38 int n, m, cnt; 39 int head[maxn], ecnt; 40 Edge edge[maxm]; 41 int bcnt, dindex; 42 int dfn[maxn], low[maxn]; 43 int stk[maxn], top; 44 int belong[maxn]; 45 int in[maxn]; 46 bool instk[maxn]; 47 bool vis[maxn]; 48 int f[maxn][maxn]; 49 50 void init() { 51 memset(edge, 0, sizeof(edge)); 52 memset(head, -1, sizeof(head)); 53 memset(instk, 0, sizeof(instk)); 54 memset(dfn, 0, sizeof(dfn)); 55 memset(low, 0, sizeof(low)); 56 memset(belong, 0, sizeof(belong)); 57 memset(in, 0, sizeof(in)); 58 ecnt = top = bcnt = dindex = 0; 59 } 60 61 void adde(int uu, int vv) { 62 edge[ecnt].u = uu; 63 edge[ecnt].v = vv; 64 edge[ecnt].next = head[uu]; 65 head[uu] = ecnt++; 66 } 67 68 void tarjan(int u) { 69 int v = u; 70 dfn[u] = low[u] = ++dindex; 71 stk[++top] = u; 72 instk[u] = 1; 73 for(int i = head[u]; ~i; i=edge[i].next) { 74 v = edge[i].v; 75 if(!dfn[v]) { 76 tarjan(v); 77 low[u] = min(low[u], low[v]); 78 } 79 else if(instk[v]) low[u] = min(low[u], dfn[v]); 80 } 81 if(dfn[u] == low[u]) { 82 bcnt++; 83 do { 84 v = stk[top--]; 85 instk[v] = 0; 86 belong[v] = bcnt; 87 } while(v != u); 88 } 89 } 90 91 queue<int> q; 92 93 int check() { 94 while(!q.empty()) { 95 int u = q.front(); q.pop(); 96 int tot = 0; 97 for(int v = 1; v <= bcnt; v++) { 98 if(!f[u][v]) continue; 99 in[v]--; 100 if(!in[v]) { 101 tot++; 102 q.push(v); 103 } 104 } 105 if(tot >= 2) return puts("Light my fire!"); 106 } 107 return puts("I love you my love and our love save us!"); 108 } 109 110 signed main() { 111 // freopen("in", "r", stdin); 112 using namespace fastIO; 113 int T, u, v; 114 read(T); 115 while(T--) { 116 read(n); read(m); 117 init(); 118 memset(f, 0, sizeof(f)); 119 for(int i = 0; i < m; i++) { 120 read(u); read(v); 121 adde(u, v); 122 } 123 for(int i = 1; i <= n; i++) { 124 if(!dfn[i]) tarjan(i); 125 } 126 for(int i = 0; i < ecnt; i++) { 127 u = belong[edge[i].u], v = belong[edge[i].v]; 128 if(u == v) continue; 129 if(f[u][v]) continue; 130 f[u][v] = 1; in[v]++; 131 } 132 while(!q.empty()) q.pop(); 133 int cnt = 0; 134 for(int i = 1; i <= bcnt; i++) { 135 if(in[i] == 0) { 136 q.push(i); 137 cnt++; 138 } 139 } 140 (cnt == 1) ? check() : puts("Light my fire!"); 141 } 142 return 0; 143 }

[HDOJ6165] FFF at Valentine(強聯通分量,縮點,拓撲排序)