luogu P2783 有机化学之神偶尔会做作弊

嘟嘟嘟

 

一道很水的黑题~~

 

边双缩点后用lca求树上两点间路径即可。

但是比较坑的是这道题是忽略重边的,结果我还特意考虑了重边,然后WA了几发。

还有两个点TLE了,原因是建新图的时候出现了重边。这个重边不是算法的问题,因为边双缩点后不可能有重边,而是写法上的问题:在建无向边的时候,习惯addEdge(x, y), addEdge(y, x),然而边双建边的时候两个点之间实际上连了4条边。所以写的时候只用建单向边,形成的图却是无向图。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<queue>
 10 #include<stack>
 11 using namespace std;
 12 #define enter puts("")
 13 #define space putchar(' ')
 14 #define Mem(a, x) memset(a, x, sizeof(a))
 15 #define rg register
 16 typedef long long ll;
 17 typedef double db;
 18 const db eps = 1e-8;
 19 const int INF = 0x3f3f3f3f;
 20 const int maxn = 1e4 + 5;
 21 const int maxe = 5e4 + 5;
 22 inline ll read()
 23 {
 24     ll ans = 0;
 25     char ch = getchar(), las = ' ';
 26     while(!isdigit(ch)) las = ch, ch = getchar();
 27     while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
 28     if(las == '-') ans = -ans;
 29     return ans;
 30 }
 31 inline void write(ll x)
 32 {
 33     if(x < 0) putchar('-'), x = -x;
 34     if(x >= 10) write(x / 10);
 35     putchar(x % 10 + '0');
 36 }
 37 
 38 int n, m;
 39 
 40 struct Edge
 41 {
 42     int nxt, to;
 43 }e[maxe << 1], e2[maxe << 1];
 44 int head[maxn], ecnt = -1;
 45 void addEdge(int x, int y)
 46 {
 47     e[++ecnt] = (Edge){head[x], y};
 48     head[x] = ecnt;
 49 }
 50 
 51 int dfn[maxn], low[maxn], cnt = 0;
 52 bool in[maxn];
 53 int st[maxn], top = 0;
 54 int col[maxn], ccol = 0;
 55 void tarjan(int now, int f)
 56 {
 57     dfn[now] = low[now] = ++cnt;
 58     st[++top] = now; in[now] = 1;
 59     for(int i = head[now]; i != -1; i = e[i].nxt)
 60     {
 61         if(!dfn[e[i].to])
 62         {
 63             tarjan(e[i].to, now);
 64             low[now] = min(low[now], low[e[i].to]);
 65         }
 66         else if(e[i].to != f) low[now] = min(low[now], dfn[e[i].to]);
 67     }
 68     if(dfn[now] == low[now])
 69     {
 70         int x; ++ccol;
 71         do
 72         {
 73             x = st[top--];
 74             col[x] = ccol;
 75             in[x] = 0;
 76         }while(x != now);
 77     }
 78 }
 79 
 80 int head2[maxn], ecnt2 = -1;
 81 void addEdge2(int x, int y)
 82 {
 83     e2[++ecnt2] = (Edge){head2[x], y};
 84     head2[x] = ecnt2;
 85 }
 86 void newGraph(int now)
 87 {
 88     int u = col[now];
 89     for(int i = head[now]; i != -1; i = e[i].nxt)
 90     {
 91         int v = col[e[i].to];
 92         if(u == v) continue;
 93         addEdge2(u, v); //addEdge2(v, u);
 94     }
 95 }
 96 
 97 const int N = 20;
 98 int fa[maxn][25], dep[maxn];
 99 void dfs(int now, int f)
100 {
101     for(int i = 1; i <= N; ++i)
102         fa[now][i] = fa[fa[now][i - 1]][i - 1];
103     for(int i = head2[now]; i != -1; i = e2[i].nxt)
104     {
105         if(e2[i].to == f) continue;
106         fa[e2[i].to][0] = now;
107         dep[e2[i].to] = dep[now] + 1;
108         dfs(e2[i].to, now);
109     }
110 }
111 int lca(int x, int y)
112 {
113     if(dep[x] < dep[y]) swap(x, y);
114     for(int i = N; i >= 0; --i)
115         if(dep[x] - (1 << i) >= dep[y]) x = fa[x][i];
116     if(x == y) return x;
117     for(int i = N; i >= 0; --i)
118         if(fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
119     return fa[x][0];
120 }
121 
122 void print(int x)
123 {
124     if(!x) return;
125     print(x >> 1);
126     write(x & 1);
127 }
128 void solve(int x, int y)
129 {
130     int z = lca(x, y);
131     print(dep[x] - dep[z] + dep[y] - dep[z] + 1);
132     enter;
133 }
134 
135 int main()
136 {
137     Mem(head, -1);
138     n = read(); m = read();
139     for(int i = 1; i <= m; ++i)
140     {
141         int x = read(), y = read();
142         addEdge(x, y); addEdge(y, x);
143     }
144     for(int i = 1; i <= n; ++i) if(!dfn[i]) tarjan(i, 0);
145     Mem(head2, -1);
146     for(int i = 1; i <= n; ++i) newGraph(i);
147     dfs(col[1], 0);
148     int q = read();
149     for(int i = 1; i <= q; ++i)
150     {
151         int x = read(), y = read();
152         solve(col[x], col[y]);
153     }
154     return 0;
155 }
View Code

 

posted @ 2018-10-27 15:56  mrclr  阅读(159)  评论(0编辑  收藏  举报