Skip to content

Commit

Permalink
LCA y Minimum Cost Arborescence
Browse files Browse the repository at this point in the history
  • Loading branch information
marioyc committed Oct 2, 2010
1 parent c5b2747 commit cef5b8d
Show file tree
Hide file tree
Showing 4 changed files with 463 additions and 0 deletions.
88 changes: 88 additions & 0 deletions Live Archive/2045 - Closest Common Ancestors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define MAX_N 100000
#define LOG2_MAXN 16

// NOTA : memset(parent,-1,sizeof(parent));
int N,parent[MAX_N],L[MAX_N];
int P[MAX_N][LOG2_MAXN];

int get_level(int u){
if(L[u]!=-1) return L[u];
else if(parent[u]==-1) return 0;
return 1+get_level(parent[u]);
}

void init(){
memset(L,-1,sizeof(L));
for(int i = 0;i<N;++i) L[i] = get_level(i);

memset(P,-1,sizeof(P));

for(int i = 0;i<N;++i) P[i][0] = parent[i];

for(int j = 1;(1<<j)<N;++j)
for(int i = 0;i<N;++i)
if(P[i][j-1]!=-1)
P[i][j] = P[P[i][j-1]][j-1];
}

int LCA(int p, int q){
if(L[p]<L[q]) swap(p,q);

int log = 1;
while((1<<log)<=L[p]) ++log;
--log;

for(int i = log;i>=0;--i)
if(L[p]-(1<<i)>=L[q])
p = P[p][i];

if(p==q) return p;

for(int i = log;i>=0;--i){
if(P[p][i]!=-1 && P[p][i]!=P[q][i]){
p = P[p][i];
q = P[q][i];
}
}

return parent[p];
}

int main(){
int u,v,m,Q,ans[MAX_N];

while(scanf("%d",&N)==1){
memset(parent,-1,sizeof(parent));

for(int i = 0;i<N;++i){
scanf("%d:(%d)",&u,&m); --u;

for(int j = 0;j<m;++j){
scanf("%d",&v); --v;
parent[v] = u;
}
}

init();
memset(ans,0,sizeof(ans));
scanf("%d\n",&Q);

for(int q = 0;q<Q;++q){
scanf("%*[\r\n ]");
scanf("(%d %d)",&u,&v);
--u; --v;
++ans[LCA(u,v)];
}

for(int i = 0;i<N;++i)
if(ans[i]!=0) printf("%d:%d\n",i+1,ans[i]);
}

return 0;
}
143 changes: 143 additions & 0 deletions PKU/3164 - Command Network.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

#define MAX_V 100
typedef double edge_cost;
edge_cost INF = 1e10;

int V,E,root,prev[MAX_V];
bool adj[MAX_V][MAX_V];
edge_cost G[MAX_V][MAX_V],MCA;
bool visited[MAX_V],circle[MAX_V];

void add_edge(int u, int v, edge_cost c){
if(adj[u][v]) G[u][v] = min(G[u][v],c);
else G[u][v] = c;
adj[u][v] = true;
}

void dfs(int v){
visited[v] = true;

for(int i = 0;i<V;++i)
if(!visited[i] && adj[v][i])
dfs(i);
}

bool check(){
memset(visited,false,sizeof(visited));
dfs(root);

for(int i = 0;i<V;++i)
if(!visited[i])
return false;

return true;
}

int exist_circle(){
prev[root] = root;

for(int i = 0;i<V;++i){
if(!circle[i] && i!=root){
prev[i] = i; G[i][i] = INF;

for(int j = 0;j<V;++j)
if(!circle[j] && adj[j][i] && G[j][i]<G[prev[i]][i])
prev[i] = j;
}
}

for(int i = 0,j;i<V;++i){
if(circle[i]) continue;
memset(visited,false,sizeof(visited));

j = i;

while(!visited[j]){
visited[j] = true;
j = prev[j];
}

if(j==root) continue;
return j;
}

return -1;
}

void update(int v){
MCA += G[prev[v]][v];

for(int i = prev[v];i!=v;i = prev[i]){
MCA += G[prev[i]][i];
circle[i] = true;
}

for(int i = 0;i<V;++i)
if(!circle[i] && adj[i][v])
G[i][v] -= G[prev[v]][v];

for(int j = prev[v];j!=v;j = prev[j]){
for(int i = 0;i<V;++i){
if(circle[i]) continue;

if(adj[i][j]){
if(adj[i][v]) G[i][v] = min(G[i][v],G[i][j]-G[prev[j]][j]);
else G[i][v] = G[i][j]-G[prev[j]][j];
adj[i][v] = true;
}

if(adj[j][i]){
if(adj[v][i]) G[v][i] = min(G[v][i],G[j][i]);
else G[v][i] = G[j][i];
adj[v][i] = true;
}
}
}
}

bool min_cost_arborescence(int _root){
root = _root;
if(!check()) return false;

memset(circle,false,sizeof(circle));
MCA = 0;

int v;

while((v = exist_circle())!=-1)
update(v);

for(int i = 0;i<V;++i)
if(i!=root && !circle[i])
MCA += G[prev[i]][i];

return true;
}

int main(){
int M,a,b;
double x[100],y[100];

while(scanf("%d %d",&V,&M)==2){
for(int i = 0;i<V;++i) scanf("%lf %lf",&x[i],&y[i]);

memset(adj,false,sizeof(adj));

for(int i = 0;i<M;++i){
scanf("%d %d",&a,&b);
--a; --b;
add_edge(a,b,sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])));
}

if(!min_cost_arborescence(0)) printf("poor snoopy\n");
else printf("%.2lf\n",MCA);
}

return 0;
}
88 changes: 88 additions & 0 deletions TJU/1051 - Closest Common Ancestors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define MAX_N 100000
#define LOG2_MAXN 16

// NOTA : memset(parent,-1,sizeof(parent));
int N,parent[MAX_N],L[MAX_N];
int P[MAX_N][LOG2_MAXN];

int get_level(int u){
if(L[u]!=-1) return L[u];
else if(parent[u]==-1) return 0;
return 1+get_level(parent[u]);
}

void init(){
memset(L,-1,sizeof(L));
for(int i = 0;i<N;++i) L[i] = get_level(i);

memset(P,-1,sizeof(P));

for(int i = 0;i<N;++i) P[i][0] = parent[i];

for(int j = 1;(1<<j)<N;++j)
for(int i = 0;i<N;++i)
if(P[i][j-1]!=-1)
P[i][j] = P[P[i][j-1]][j-1];
}

int LCA(int p, int q){
if(L[p]<L[q]) swap(p,q);

int log = 1;
while((1<<log)<=L[p]) ++log;
--log;

for(int i = log;i>=0;--i)
if(L[p]-(1<<i)>=L[q])
p = P[p][i];

if(p==q) return p;

for(int i = log;i>=0;--i){
if(P[p][i]!=-1 && P[p][i]!=P[q][i]){
p = P[p][i];
q = P[q][i];
}
}

return parent[p];
}

int main(){
int u,v,m,Q,ans[MAX_N];

while(scanf("%d",&N)==1){
memset(parent,-1,sizeof(parent));

for(int i = 0;i<N;++i){
scanf("%d:(%d)",&u,&m); --u;

for(int j = 0;j<m;++j){
scanf("%d",&v); --v;
parent[v] = u;
}
}

init();
memset(ans,0,sizeof(ans));
scanf("%d\n",&Q);

for(int q = 0;q<Q;++q){
scanf("%*[\r\n ]");
scanf("(%d%*[\r\n ,]%d)",&u,&v);
--u; --v;
++ans[LCA(u,v)];
}

for(int i = 0;i<N;++i)
if(ans[i]!=0) printf("%d:%d\n",i+1,ans[i]);
}

return 0;
}
Loading

0 comments on commit cef5b8d

Please sign in to comment.