给定一张连通图,求所有生成树中最大边权与最小边权差最小的,输出它们的差值……
   
一 题目
原题链接
描述
求所有生成树中最大边权与最小边权差最小的,输出它们的差值。
输入
输入文件包含多组测试数据,每组测试数据如下: 第1行:2个整数n m (2 ≤ n ≤ 100 and 0 ≤ m ≤ n(n − 1)/2),n表示顶点数,m表示边数。接下来m行,每行3个空格分开的整数a b w(1 ≤ w ≤ 10000) , 表示顶点a与顶点b之间有一条边,权值为w。
输出
对每组测试数据,如果图存在生成树,输出生成树的差值最小的;否则,输出-1。
二 题解
$n$不大,考虑暴力。
把边权升序排序,每次固定mst的第一条边,那么最后一条边也肯定固定了。(贪心原理:最后一条边越靠前差值越少)。枚举起始边,kruskal求最小生成树,维护最优解就好了。
复杂度大约是$O(q(m^2 +mlogm))$。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
   | #include<iostream> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std;
  int read(){     int s=0,ne=1; char c=getchar();     for(;c<'0'||c>'9';c=getchar()) if(c=='-') ne=-1;     for(;c>='0'&&c<='9';c=getchar()) s=(s<<1)+(s<<3)+c-'0';     return s*ne; }
  const int CP=110; const int CE=CP*CP;
  const int INF=0x3f3f3f3f;
  class fs{   public:       int from,to,dist;       void init(int f,int t,int d)       {from=f; to=t; dist=d;}       bool operator < (const fs& e)const {return dist<e.dist;} }E[CE]; int ecnt=0; void add(int x,int y,int z){     E[++ecnt].init(x,y,z); }
 
  class ufs{    public:       int fa[CP];       ufs() {for(int i=1;i<CP;i++) fa[i]=i;}       void init() {for(int i=1;i<CP;i++) fa[i]=i;}       int find(int u) {return fa[u]==u ? u : fa[u]=find(fa[u]);}       bool exm(int x,int y) {return find(x)!=find(y);}       void merge(int x,int y) {fa[find(x)]=find(y);} }s;
 
  int n,m;
 
  int mst() {     sort(E+1,E+ecnt+1);          int ans=INF;     for(int st=1; st<=ecnt; st++)      {         s.init();         int cnt=0,lst=-1;                 for(int k=st; k<=ecnt&&cnt!=n-1; k++)          {             fs e=E[k];             if(!s.exm(e.from,e.to)) continue;             s.merge(e.from,e.to);             lst=k; cnt++;         }                  if(cnt != n-1) continue;          ans = min(ans, E[lst].dist-E[st].dist);      }          return ans==INF ? -1 : ans; }
  int main() {     
      n=read(); m=read();     while(n)     {         ecnt = 0;          while(m--) {             int x=read(),y=read(),z=read();             add(x,y,z);         }                  printf("%d\n",mst());                  n=read(); m=read();     }          return 0; }
   |