• cf 609E.Minimum spanning tree for each edge


    最小生成树,lca(树链剖分(太难搞,不会写))

    问存在这条边的最小生成树,2种情况。1.这条边在原始最小生成树上。2.加上这条半形成一个环(加上),那么就找原来这条边2端点间的最大边就好(减去)。(sum+val-max)

    (代码冗长)

      1 #include<bits/stdc++.h>
      2 #define LL long long 
      3 #define  N 100005
      4 using namespace std;
      5 inline int ra()
      6 {
      7     int x=0,f=1; char ch=getchar();
      8     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
      9     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
     10     return x*f;
     11 }
     12 struct node{
     13     int x,y,id,v;
     14 }a[N<<1];
     15 struct data{
     16     int to,next,v;
     17 }e[N<<2];
     18 int n,m,deep[N<<1],fa[N<<1][21];
     19 int father[N<<1],cnt;
     20 LL sum;
     21 int mx[N<<1][21],head[N<<1];
     22 bool vis[N<<1];
     23 void insert(int x, int y, int v)
     24 {
     25     e[++cnt].next=head[x];
     26     e[cnt].to=y;
     27     e[cnt].v=v;
     28     head[x]=cnt;
     29 }
     30 int find(int x)
     31 {
     32     return father[x]==x?x:father[x]=find(father[x]);
     33 }
     34 bool cmp(node a, node b)
     35 {
     36     return a.v<b.v;
     37 }
     38 bool cmpid(node a, node b)
     39 {
     40     return a.id<b.id;
     41 }
     42 void dfs(int x, int f)
     43 {
     44     for (int i=1; i<=20; i++)
     45     {
     46         fa[x][i]=fa[fa[x][i-1]][i-1];
     47         mx[x][i]=max(mx[x][i-1],mx[fa[x][i-1]][i-1]);
     48     }
     49     for (int i=head[x];i;i=e[i].next)
     50     {
     51         if (e[i].to==f) continue;
     52         fa[e[i].to][0]=x;
     53         mx[e[i].to][0]=e[i].v;
     54         deep[e[i].to]=deep[x]+1;
     55         dfs(e[i].to,x);
     56     }
     57 }
     58 int getans(int x, int y)
     59 {
     60     int ans=0;
     61     if (deep[x]<deep[y]) swap(x,y);
     62     int t=deep[x]-deep[y];
     63     for (int i=0; i<=20; i++)
     64         if (t&(1<<i)) ans=max(ans,mx[x][i]),x=fa[x][i];
     65     for (int i=20; i>=0; i--)
     66         if (fa[x][i]!=fa[y][i])
     67         {
     68             ans=max(ans,max(mx[x][i],mx[y][i]));
     69             x=fa[x][i]; y=fa[y][i];
     70         }
     71     if (x!=y) return max(ans,max(mx[x][0],mx[y][0]));
     72     return ans;
     73 }
     74 int main()
     75 {
     76     n=ra(); m=ra();
     77     for (int i=1; i<=m; i++)
     78     {
     79         int x=ra(),y=ra(),v=ra();
     80         a[i].x=x; a[i].y=y; a[i].v=v; a[i].id=i;
     81     }
     82     sort(a+1,a+m+1,cmp); int tot=0;
     83     for (int i=1; i<=n; i++) father[i]=i;
     84     for (int i=1; i<=m; i++)
     85     {
     86         int q=find(a[i].x),p=find(a[i].y);
     87         if (p!=q)
     88         {
     89             vis[a[i].id]=1;
     90             father[p]=q;
     91             sum+=a[i].v;
     92             tot++;
     93             insert(a[i].x,a[i].y,a[i].v);
     94             insert(a[i].y,a[i].x,a[i].v);
     95     //        cout<<a[i].x<<"   "<<a[i].y<<"    "<<a[i].v<<endl;
     96         }
     97         if (tot==n-1) break;
     98     }
     99     dfs(1,0);
    100     sort(a+1,a+m+1,cmpid);
    101     for (int i=1; i<=m; i++)
    102     {
    103         if (vis[i]) printf("%I64d
    ",sum);
    104         else {
    105             cout<<sum+(LL)a[i].v-(LL)getans(a[i].x,a[i].y)<<endl;
    106         //    cout<<getans(a[i].x,a[i].y);while (1);
    107         }
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    Graphviz安装配置
    固定ip
    机器学习基础
    研究生入学感悟
    复试临时练习
    复试临时练习
    Dev-C++回文数遇到的小麻烦
    单例模式
    工厂方法模式
    Spark的checkpoint详解
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6368254.html
Copyright © 2020-2023  润新知