题意:给出一个
暴力分块!!!
对于不同的数据采取不同的暴力方式,即可通过这道题。
对于每种颜色,统计这种颜色的边有多少,如果大于
如果小于
最后统计答案时要用 map 统计,存边时用 vector 即可。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#include<ctime>
#include<map>
#define INF 1e9
using namespace std;
const int maxn=200010;
const double Pi=acos(-1.0);
template<class T>void read(T &x)
{
x=0;int f=0;char ch=getchar();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}
int n,m,q,fa[maxn],size[maxn],vis[maxn],qx[maxn],qy[maxn];
int head[maxn],cnt,num[maxn],r[maxn],tot;
map<pair<int,int>,int > ans,v;
vector<pair<int,int> > e[maxn],o;
int min(int a,int b)
{
return a<b?a:b;
}
int max(int a,int b)
{
return a>b?a:b;
}
int getfa(int u)
{
if(fa[u]==u)
return u;
return fa[u]=getfa(fa[u]);
}
void merge(int a,int b)
{
a=getfa(a);
b=getfa(b);
if(a!=b)
{
if(size[a]<size[b])
{
fa[a]=b;
size[b]+=size[a];
}
else
{
fa[b]=a;
size[a]+=size[b];
}
}
}
void count_question(int c)
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
size[i]=1;
}
vector<pair<int,int> >::iterator it;
for(it=e[c].begin();it!=e[c].end();it++)
merge(it->first,it->second);
for(it=o.begin();it!=o.end();it++)
{
int a=min(it->first,it->second);
int b=max(it->first,it->second);
if(getfa(a)==getfa(b))
++ans[make_pair(a,b)];
}
}
void count_points(int c)
{
memset(vis,0,sizeof(vis));
tot=0;
vector<pair<int,int> >::iterator it;
for(it=e[c].begin();it!=e[c].end();it++)
{
if(!vis[it->first])
{
r[++tot]=it->first;
fa[r[tot]]=r[tot];//初始化fa和size一定只对这种颜色的点更新!!!否则会TLE!!!
size[r[tot]]=1;
vis[it->first]=1;
}
if(!vis[it->second])
{
r[++tot]=it->second;
fa[r[tot]]=r[tot];
size[r[tot]]=1;
vis[it->second]=1;
}
merge(it->first,it->second);
}
for(int i=1;i<=tot;i++)
for(int j=i+1;j<=tot;j++)
if(r[i]!=r[j])
{
int a=min(r[i],r[j]);
int b=max(r[i],r[j]);
int x=getfa(a);
int y=getfa(b);
if(x==y)
++ans[make_pair(a,b)];
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
num[c]++;
e[c].push_back(make_pair(min(a,b),max(a,b)));
}
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d",&qx[i],&qy[i]);
if(!ans.count(make_pair(min(qx[i],qy[i]),max(qx[i],qy[i]))))
{
o.push_back(make_pair(min(qx[i],qy[i]),max(qx[i],qy[i])));
ans[make_pair(min(qx[i],qy[i]),max(qx[i],qy[i]))]=0;
}
}
for(int i=1;i<=m;i++)
if(num[i])
{
if(num[i]>=sqrt(m))
count_question(i);
else
count_points(i);
}
for(int i=1;i<=q;i++)
printf("%d\n",ans[make_pair(min(qx[i],qy[i]),max(qx[i],qy[i]))]);
return 0;
}