加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Drivers Dissatisfaction 最小生成树+LCA

发布时间:2020-12-14 04:15:08 所属栏目:大数据 来源:网络整理
导读:题意:给一张n个点m条边的连通图,每条边(ai,bi)有一个权值wi和费用ci, 表示这条边每降低1的权值需要ci的花费。现在一共有S费用可以用来降低某些边的权值 (可以降到负数),求图中的一棵权值和最小的生成树并输出方案 显然是找到一条边然后将这条边减到最

题意:给一张n个点m条边的连通图,每条边(ai,bi)有一个权值wi和费用ci,

表示这条边每降低1的权值需要ci的花费。现在一共有S费用可以用来降低某些边的权值

(可以降到负数),求图中的一棵权值和最小的生成树并输出方案

显然是找到一条边然后将这条边减到最小

先跑一边最小生成树,找到树上最小的一点,然后在枚举其他的边,

加上这条边会产生一个环,所以需要删除这个环上面权值最大的边

这个通过类似于LCA倍增的手法做到,

?

?

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <set>
  7 #include <iostream>
  8 #include <map>
  9 #include <stack>
 10 #include <string>
 11 #include <vector>
 12 #define  pi acos(-1.0)
 13 #define  eps 1e-6
 14 #define  fi first
 15 #define  se second
 16 #define  rtl   rt<<1
 17 #define  rtr   rt<<1|1
 18 #define  bug         printf("******n")
 19 #define  mem(a,b)    memset(a,b,sizeof(a))
 20 #define  name2str(x) #x
 21 #define  fuck(x)     cout<<#x" = "<<x<<endl
 22 #define  f(a)        a*a
 23 #define  sf(n)       scanf("%d",&n)
 24 #define  sff(a,b)    scanf("%d %d",&a,&b)
 25 #define  sfff(a,c) scanf("%d %d %d",&b,&c)
 26 #define  sffff(a,c,d) scanf("%d %d %d %d",&c,&d)
 27 #define  pf          printf
 28 #define  FRE(i,a,b)  for(i = a; i <= b; i++)
 29 #define  FREE(i,b) for(i = a; i >= b; i--)
 30 #define  FRL(i,b)  for(i = a; i < b; i++)+
 31 #define  FRLL(i,b) for(i = a; i > b; i--)
 32 #define  FIN         freopen("data.txt","r",stdin)
 33 #define  gcd(a,b)    __gcd(a,b)
 34 #define  lowbit(x)   x&-x
 35 using namespace std;
 36 typedef long long  LL;
 37 typedef unsigned long long ULL;
 38 const int mod = 1e9 + 7;
 39 const int maxn = 2e5 + 10;
 40 const int INF = 0x3f3f3f3f;
 41 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
 42 int n,m,c[maxn],w[maxn],fa[maxn],vis[maxn];
 43 int dep[maxn],p[maxn][21],maxx[maxn][21];
 44 struct Edge {
 45     int u,v,w,id;
 46 } edge[maxn];
 47 int cmp ( Edge a,Edge b ) {
 48     return a.w < b.w;
 49 }
 50 struct xxx {
 51     int v,id;
 52     xxx ( int v,int id ) : v ( v ),id ( id ) {}
 53 };
 54 vector<xxx>mp[maxn];
 55 int Find ( int x ) {
 56     return fa[x] == x ? x : fa[x] = Find ( fa[x] );
 57 }
 58 void dfs ( int u,int f,int id ) {
 59     dep[u] = dep[f] + 1,p[u][0] = f,maxx[u][0] = id;
 60     for ( int i = 1 ; i <= 20 ; i++ ) {
 61         if ( dep[u] - ( 1 << i ) <= 0 ) break;
 62         int v = p[u][i - 1];
 63         p[u][i] = p[v][i - 1];
 64         if ( w[maxx[u][i - 1]] < w[maxx[v][i - 1]] ) maxx[u][i] = maxx[v][i - 1];
 65         else maxx[u][i] = maxx[u][i - 1];
 66     }
 67     for ( int i = 0 ; i < mp[u].size() ; i++ ) {
 68         int v = mp[u][i].v,id = mp[u][i].id;
 69         if ( v != f ) dfs ( v,u,id );
 70     }
 71 }
 72 int get_max ( int x,int y ) {
 73     if ( dep[x] < dep[y] ) swap ( x,y );
 74     int temp = 0,ans = 0;
 75     for ( int i = 20 ; i >= 0 ; i-- ) {
 76         if ( dep[x] - ( 1 << i ) >= dep[y] ) {
 77             if ( w[maxx[x][i]] > temp ) ans = maxx[x][i],temp = w[ans];
 78             x = p[x][i];
 79         }
 80     }
 81     if ( x == y ) return ans;
 82     for ( int i = 20 ; i >= 0 ; i-- ) {
 83         if ( dep[x] - ( 1 << i ) > 0 && p[x][i] != p[y][i] ) {
 84             if ( w[maxx[x][i]] > temp ) ans = maxx[x][i],temp = w[ans];
 85             if ( w[maxx[y][i]] > temp ) ans = maxx[y][i],temp = w[ans];
 86             x = p[x][i],y = p[y][i];
 87             if ( x == y ) break;
 88         }
 89     }
 90     if ( w[maxx[x][0]] > temp ) ans = maxx[x][0],temp = w[ans];
 91     if ( w[maxx[y][0]] > temp ) ans = maxx[y][0],temp = w[ans];
 92     return ans;
 93 }
 94 int main() {
 95     sff ( n,m );
 96     for ( int i = 1 ; i <= m ; i++ ) sf ( w[i] );
 97     for ( int i = 1 ; i <= m ; i++ ) sf ( c[i] );
 98     for ( int i = 1 ; i <= m ; i++ ) {
 99         sff ( edge[i].u,edge[i].v );
100         edge[i].w = w[i],edge[i].id = i;
101     }
102     sort ( edge + 1,edge + 1 + m,cmp );
103     LL sum = 0,s,minn = INF,idx = 0,k = 0;
104     scanf ( "%lld",&s );
105     for ( int i = 1 ; i <= n ; i++ ) fa[i] = i;
106     for ( int i = 1 ; i <= m ; i++ ) {
107         int nx = Find ( edge[i].v ),ny = Find ( edge[i].u );
108         if ( nx == ny ) continue;
109         fa[nx] = ny;
110         sum += edge[i].w;
111         vis[edge[i].id] = 1,k++;
112         if ( c[edge[i].id] < minn )  idx = edge[i].id,minn = c[edge[i].id];
113         mp[edge[i].u].push_back ( xxx ( edge[i].v,edge[i].id ) );
114         mp[edge[i].v].push_back ( xxx ( edge[i].u,edge[i].id ) );
115         if ( k == n - 1 ) break;
116     }
117     LL ans = sum - s / minn;
118     dep[0] = 0;
119     dfs ( 1,0,0 );
120     int del = 0;
121     for ( int i = 1 ; i <= m ; i++ ) {
122         if ( vis[edge[i].id]  ) continue;
123         int cnt = get_max ( edge[i].u,edge[i].v );
124         if ( cnt == 0 ) continue;
125         LL temp = sum - w[cnt] + w[edge[i].id] - s / c[edge[i].id];
126         if ( temp < ans ) ans = temp,idx = edge[i].id,del = cnt;
127     }
128     if ( del ) vis[del] = 0,vis[idx] = 1;
129     printf ( "%lldn",ans );
130     w[idx] -= s / c[idx];
131     for ( int i = 1 ; i <= m ; i++ ) if ( vis[i] ) printf ( "%d %dn",i,w[i] );
132     return 0;
133 }
View Code

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读