1906: 树上的蚂蚁
Time Limit: 25 Sec Memory Limit: 162 MBSubmit: 80 Solved: 15
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
1
3
1 2 1
2 3 1
3
1 3 2
3 1 1
1 2 3
3
1 2 1
2 3 1
3
1 3 2
3 1 1
1 2 3
Sample Output
2
HINT
N< = 100000
Source
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 2E5 + 20;
const int N = 18;
typedef long long LL;
struct E{
int to,w; E(){}
E(int to,int w): to(to),w(w){}
};
int n,m,dfs_clock,T,ans,L[maxn][N],Ans[maxn][N],bin[maxn],len[maxn]
,s[maxn],t[maxn],v[maxn],lca[maxn],dfn[maxn],A[5],dis[maxn];
bool ok[1010][1010];
vector <E> G[maxn];
bool cmp(const int &x,const int &y) {return dfn[x] < dfn[y];}
int getint()
{
char ch = getchar(); int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret*10 + ch - '0',ch = getchar();
return ret;
}
void Clear()
{
for (int i = 1; i <= n; i++)
{
G[i].clear(); dis[i] = 0; dfs_clock = 0;
//memset(Ans[i],0,sizeof(Ans[i]));
//memset(L[i],0,sizeof(L[i]));
}
}
void Dfs(int x,int fa)
{
dfn[x] = ++dfs_clock;
Ans[dfs_clock][0] = x;
for (int i = 0; i < G[x].size(); i++)
{
E e = G[x][i];
if (e.to == fa) continue;
dis[e.to] = dis[x] + e.w;
L[dfs_clock+1][0] = L[dfn[x]][0] + 1;
Dfs(e.to,x); ++dfs_clock;
L[dfs_clock][0] = L[dfn[x]][0];
Ans[dfs_clock][0] = x;
}
}
int LCA(int x,int y)
{
x = dfn[x]; y = dfn[y]; if (x > y) swap(x,y);
int le = y - x + 1,k = bin[le];
if (L[x][k] < L[y-len[le]+1][k]) return Ans[x][k];
else return Ans[y-len[le]+1][k];
}
int Dis(const int &x,const int &y)
{
int lca = LCA(x,y);
return dis[x] + dis[y] - 2*dis[lca];
}
void Pre_Work()
{
for (int j = 1; j < N; j++)
for (int i = 1; i <= dfs_clock; i++)
{
int Nex = i + (1<<j-1);
if (Nex > dfs_clock) break;
if (L[Nex][j-1] < L[i][j-1])
L[i][j] = L[Nex][j-1],Ans[i][j] = Ans[Nex][j-1];
else L[i][j] = L[i][j-1],Ans[i][j] = Ans[i][j-1];
}
m = getint();
for (int i = 1; i <= m; i++)
{
s[i] = getint(); t[i] = getint();
lca[i] = LCA(s[i],t[i]); v[i] = getint();
}
}
void Work(const int &X,const int &Y,const int &i,const int &j)
{
bool f1 = (Dis(A[X],s[i]) < Dis(A[Y],s[i])); int s1 = f1?A[X]:A[Y];
bool f2 = (Dis(A[X],s[j]) < Dis(A[Y],s[j])); int s2 = f2?A[X]:A[Y];
if (f1 == f2)
{
int t1 = s1 == A[X]?A[Y]:A[X],t2 = t1;
int sa = Dis(s1,s[i]),sb = Dis(s2,s[j]);
int sc = Dis(t1,s[i]),sd = Dis(t2,s[j]);
if (1LL*sa*v[j] == 1LL*sb*v[i]) ++ans;
else if (1LL*sa*v[j] <= 1LL*sb*v[i])
{
if (1LL*sd*v[i] <= 1LL*sc*v[j]) ++ans;
}
else
{
if (1LL*sc*v[j] <= 1LL*sd*v[i]) ++ans;
}
}
else
{
int t1 = s1 == A[X]?A[Y]:A[X],t2 = s2 == A[X]?A[Y]:A[X];
int sa = Dis(s1,s[i]),sb = Dis(s2,s[j]);
int sc = Dis(t1,s[i]),sd = Dis(t2,s[j]);
if (1LL*sa*v[j] <= 1LL*sb*v[i] && 1LL*sb*v[i] <= 1LL*sc*v[j]) ++ans;
else if (1LL*sb*v[i] <= 1LL*sa*v[j] && 1LL*sa*v[j] <= 1LL*sd*v[i]) ++ans;
}
}
bool Judge(int x,int i)
{
if (LCA(x,lca[i]) != lca[i]) return 0;
if (LCA(x,s[i]) != x && LCA(x,t[i]) != x) return 0;
return 1;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
for (int i = 1; i < maxn; i++)
{
bin[i] = (1<<bin[i-1]+1) < i?bin[i-1]+1:bin[i-1];
len[i] = (1<<bin[i]);
}
T = getint();
while (T--)
{
n = getint(); Clear();
for (int i = 1; i < n; i++)
{
int x = getint(),y,w;
y = getint(); w = getint();
G[x].push_back(E(y,w));
G[y].push_back(E(x,w));
}
L[1][0] = 1; Dfs(1,0); Pre_Work(); ans = 0;
for (int i = 1; i < m; i++)
for (int j = i + 1; j <= m; j++)
{
if (s[i] == s[j]) {++ans; ok[i][j] = 1; continue;}
int Z = ans;
A[1] = LCA(s[i],s[j]); A[2] = LCA(s[i],t[j]);
A[3] = LCA(t[i],s[j]); A[4] = LCA(t[i],t[j]);
sort(A + 1,A + 5,cmp); int tot = 0;
for (int k = 1; k <= 4; k++)
if (A[k] != A[k-1] && Judge(A[k],i) && Judge(A[k],j))
A[++tot] = A[k];
if (!tot) continue;
else if (tot == 1)
{
int sa = Dis(A[1],s[i]),sb = Dis(A[1],s[j]);
if (1LL*sa*v[j] == 1LL*sb*v[i]) ++ans;
}
else if (tot == 2) Work(1,2,i,j); else Work(2,3,i,j);
if (Z != ans) ok[i][j] = 1;
}
printf("%d\n",ans);
}
return 0;
}