1. 程式人生 > >洛谷P2783 有機化學之神偶爾會作弊

洛谷P2783 有機化學之神偶爾會作弊

display getchar() closed 標記 ide algo mic void 技術分享

  題目傳送門

  啦啦啦,發個文紀念一下第一道在洛谷上A的黑題,一次性就過真是無比舒服~(雖然某些大佬說這題有點水……)題目其實思路不難,Tarjan縮點+LCA,不過因為是無向邊,所以在Tarjan的時候做點標記就行了,不過第四個點會被卡,用vector存邊就可以A掉了。另外輸出用二進制這個應該沒什麽好說的。

  下面放代碼:

  

技術分享圖片
#include<cmath>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include
<cstdlib> #include<iostream> #include<algorithm> using namespace std; const int N=10001; const int M=50001; int n,m,T,indexx,id,dep[N]; int low[N],dfn[N],size[N]; int f[N][21],belong[N]; bool vis[N]; vector<int>edge[M<<1]; vector<int>node[M<<1]; stack<int
>team; inline int read() { char ch=getchar();int num=0;bool flag=false; while(ch<0||ch>9){if(ch==-)flag=true;ch=getchar();} while(ch>=0&&ch<=9){num=num*10+ch-0;ch=getchar();} return flag?-num:num; } inline int Min(int x,int y) {return x<y?x:y;} inline
void tarjan(int u,int last) { dfn[u]=low[u]=++indexx; vis[u]=true;team.push(u); for(int i=0;i<node[u].size();i++){ int v=node[u][i]; if(v==last)continue; if(!dfn[v]){ tarjan(v,u); low[u]=Min(low[u],low[v]);} else if(vis[v]) low[u]=Min(low[u],dfn[v]); } if(dfn[u]==low[u]){ int v;++id; do{ v=team.top();team.pop(); vis[v]=false; belong[v]=id;size[id]++; }while(v!=u); } } void build() { for(int i=1;i<=n;i++) for(int j=0;j<node[i].size();j++){ int v=node[i][j]; if(belong[i]!=belong[v]) edge[belong[i]].push_back(belong[v]); } } inline void dfs(int u,int fa,int depth) { dep[u]=depth;f[u][0]=fa; for(int i=0;i<edge[u].size();i++) if(edge[u][i]!=fa) dfs(edge[u][i],u,depth+1); } void init() { for(int j=1;j<=20;j++) for(int i=1;i<=id;i++) f[i][j]=f[f[i][j-1]][j-1]; } inline int LCA(int a,int b) { if(dep[a]<dep[b])swap(a,b); for(int i=20;i>=0;i--) if(dep[f[a][i]]>=dep[b]) a=f[a][i]; if(a==b)return a; for(int i=20;i>=0;i--) if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i]; return f[a][0]; } inline void print(int x) { if(x==0)return; print(x>>1); putchar(x%2+0); } int main() { n=read();m=read(); for(int i=1;i<=m;i++){ int x=read();int y=read(); node[x].push_back(y); node[y].push_back(x);} for(int i=1;i<=n;i++) if(!dfn[i])tarjan(i,0); build();dfs(1,0,0);init(); T=read(); for(int i=1;i<=T;i++){ int x=read();int y=read(); x=belong[x],y=belong[y]; int lca=LCA(x,y); print((dep[x]+dep[y])-(dep[lca]<<1)+1); printf("\n"); } return 0; }
View Code

洛谷P2783 有機化學之神偶爾會作弊