您的位置:首页 > 其它

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

2018-10-27 15:56 344 查看

嘟嘟嘟

 

一道很水的黑题~~

 

边双缩点后用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

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: