标签:
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 952 Accepted Submission(s): 422

题目大意:
给一无向图,n个点,m条边,每条边有个长度,且不一样。定义f(i,j)表示从节点i到节点j的所有路径中的最大边权值的最小值。有q个询问,每个询问有个t,求f(i,j)>=t的种数。
从小到大开始枚举啊,相当于最小生成树啊,然后 二分查找答案就好了。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#define maxn 500010
using namespace std;
vector<int> ans;
struct node
{
int x,y,w;
}e[maxn];
int n,m,tot[maxn],q,sum[maxn],fa[maxn];
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
bool cmp(node a,node b)
{
return a.w<b.w;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int cnt=1;
for(int i=0;i<maxn;i++)
{
fa[i]=i;
sum[i]=1;
tot[i]=0;
}
ans.clear();
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
}
sort(e,e+m,cmp);
for(int i=0;i<m;i++)
{
int fx,fy;
fx=find(e[i].x),fy=find(e[i].y);
if(fx!=fy)
{
fa[fx]=fy;
ans.push_back(e[i].w);
tot[cnt++]=sum[fx]*sum[fy]*2;
sum[fy]+=sum[fx];
}
}
for(int i=1;i<cnt;i++)
tot[i]+=tot[i-1];
scanf("%d",&q);
while(q--)
{
int x;
scanf("%d",&x);
int pos=lower_bound(ans.begin(),ans.end(),x)-ans.begin();
printf("%d\n",tot[cnt-1]-tot[pos]);
}
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/water-full/p/4534352.html