NC19855. K小生成树(kmst)
描述
输入描述
第一行两个正整数n,m,表示点数和边数。
接下来m行,每行三个整数u,v,val,描述一条边。
接下来一行一个正整数q,表示询问的组数。
接下来q行,每行两个整数L,R,意义如“题目描述”
输出描述
对于每一组询问,输出一个非负整数表示答案。
示例1
输入:
3 5 1 2 1 1 3 2 1 3 7 2 3 4 2 3 3 2 3 11 6 9
输出:
8 2
示例2
输入:
5 8 1 2 3 1 3 10 1 4 4 1 5 2 2 4 7 2 5 5 2 3 6 3 4 8 1 15 30
输出:
40
说明:
对于30%的数据,n<=8,L,R<=100C++11(clang++ 3.9) 解法, 执行用时: 1112ms, 内存消耗: 736K, 提交时间: 2018-11-03 14:58:07
#include <cstdio> #include <cstring> #define F(i,x,y) for(int i=x;i<=y;++i) using namespace std; const int M=30; int from[M],to[M],val[M],fa[M]; int n,m,q; int A[10010],B[10010],ans[10010]; int G(int x){ return fa[x]==x?x:G(fa[x]); } void dfs(int x,int s,int t){ if(t==n-1){ F(i,1,q){ if(s>=A[i]&&s<=B[i]){ ans[i]++; } } return ; } if(x==m+1) return ; dfs(x+1,s,t); int fx=G(from[x]),fy=G(to[x]); if(fx!=fy){ fa[fx]=fy; dfs(x+1,s+val[x],t+1); fa[fx]=fx; } } int main(){ scanf("%d%d",&n,&m); F(i,1,n) fa[i]=i; F(i,1,m){ scanf("%d%d%d",&from[i],&to[i],&val[i]); } scanf("%d",&q); F(i,1,q){ scanf("%d%d",&A[i],&B[i]); } dfs(1,0,0); F(i,1,q) printf("%d\n",ans[i]); return 0; }