Drivers Dissatisfaction
In one kingdom there are n cities and m two-way roads. Each road connects a pair of cities, and for each road we know the level of drivers dissatisfaction — the value wi.
For each road we know the value ci — how many lamziks we should spend to reduce the level of dissatisfaction with this road by one. Thus, to reduce the dissatisfaction with the i-th road by k, we should spend k·ci lamziks. And it is allowed for the dissatisfaction to become zero or even negative.
In accordance with the king's order, we need to choose n - 1 roads and make them the main roads. An important condition must hold: it should be possible to travel from any city to any other by the main roads.
The road ministry has a budget of S lamziks for the reform. The ministry is going to spend this budget for repair of some roads (to reduce the dissatisfaction with them), and then to choose the n - 1 main roads.
Help to spend the budget in such a way and then to choose the main roads so that the total dissatisfaction with the main roads will be as small as possible. The dissatisfaction with some roads can become negative. It is not necessary to spend whole budget S.
It is guaranteed that it is possible to travel from any city to any other using existing roads. Each road in the kingdom is a two-way road.
The first line contains two integers n and m (2 ≤ n ≤ 2·105, n - 1 ≤ m ≤ 2·105) — the number of cities and the number of roads in the kingdom, respectively.
The second line contains m integers w1, w2, ..., wm (1 ≤ wi ≤ 109), where wi is the drivers dissatisfaction with the i-th road.
The third line contains m integers c1, c2, ..., cm (1 ≤ ci ≤ 109), where ci is the cost (in lamziks) of reducing the dissatisfaction with the i-th road by one.
The next m lines contain the description of the roads. The i-th of this lines contain a pair of integers ai and bi (1 ≤ ai, bi ≤ n, ai ≠ bi) which mean that the i-th road connects cities ai and bi. All roads are two-way oriented so it is possible to move by the i-th road from aito bi, and vice versa. It is allowed that a pair of cities is connected by more than one road.
The last line contains one integer S (0 ≤ S ≤ 109) — the number of lamziks which we can spend for reforms.
In the first line print K — the minimum possible total dissatisfaction with main roads.
In each of the next n - 1 lines print two integers x, vx, which mean that the road x is among main roads and the road x, after the reform, has the level of dissatisfaction vx.
Consider that roads are numbered from 1 to m in the order as they are given in the input data. The edges can be printed in arbitrary order. If there are several answers, print any of them.
6 9
1 3 1 1 3 1 2 2 2
4 1 4 2 2 5 3 1 6
1 2
1 3
2 3
2 4
2 5
3 5
3 6
4 5
5 6
7
0
1 1
3 1
6 1
7 2
8 -5
3 3
9 5 1
7 7 2
2 1
3 1
3 2
2
5
3 0
2 5
分析:题目大意是有n个点,m条路,每条路有不满意度w[i],以及减小一个不满意度代价c[i],
问给你s元,找到一个总不满意度最小的生成树,保证有解;
经过观察可以发现我们用S元总是对一条路使用的;
所以跑一遍最小生成树求得初始最小花费;
枚举不在树上的边,加入后形成环,删去这条边两个节点路上w[j]最大的边,判断是否更优;
两个节点经过的路边的最大值可以用倍增lca,或树链剖分;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <unordered_map> #include <queue> #include <stack> #include <vector> #include <list> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define Lson L, mid, ls[rt] #define Rson mid+1, R, rs[rt] #define sys system("pause") #define freopen freopen("in.txt","r",stdin) const int maxn=2e5+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} inline ll read() { ll x=0;int f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,k,t,fa[20][maxn],dep[maxn],w[maxn],c[maxn],ok[maxn],pq[maxn],u[maxn],v[maxn],p[maxn],s; vi ans; vector<pii>e[maxn]; pii ex,ey,st[20][maxn]; ll sum,best; int find(int x){return p[x]==x?x:p[x]=find(p[x]);} void dfs(int p) { for(int i=1;fa[i-1][p];i++) { fa[i][p]=fa[i-1][fa[i-1][p]]; st[i][p]=max(st[i-1][p],st[i-1][fa[i-1][p]]); } for(pii x:e[p]) { int to=x.fi,q=x.se; if(to==fa[0][p])continue; dep[to]=dep[p]+1; fa[0][to]=p; st[0][to]=mp(w[q],q); dfs(to); } } pii max_lca(int a,int b) { pii ma=mp(0,0); if(dep[a]<dep[b])swap(a,b); for(int i=19;i>=0;i--) if(dep[fa[i][a]]>=dep[b])ma=max(ma,st[i][a]),a=fa[i][a]; if(a==b)return ma; for(int i=19;i>=0;i--) { if(fa[i][a]!=fa[i][b]) { ma=max(ma,st[i][a]); ma=max(ma,st[i][b]); a=fa[i][a]; b=fa[i][b]; } } ma=max(ma,st[0][a]); ma=max(ma,st[0][b]); return ma; } int main() { int i,j; n=read(),m=read(); rep(i,1,m)w[i]=read(); rep(i,1,m)c[i]=read(); rep(i,1,m)u[i]=read(),v[i]=read(),pq[i]=i; scanf("%d",&s); sort(pq+1,pq+m+1,[](const int&x,const int&y){return w[x]<w[y];}); rep(i,1,n)p[i]=i; ex=mp(inf,inf); rep(i,1,m) { int x=find(u[pq[i]]),y=find(v[pq[i]]); if(x!=y) { p[x]=y; sum+=w[pq[i]]; ex=min(ex,mp(c[pq[i]],pq[i])); ans.pb(pq[i]); e[u[pq[i]]].pb(mp(v[pq[i]],pq[i])); e[v[pq[i]]].pb(mp(u[pq[i]],pq[i])); } else ok[pq[i]]=1; } dfs(1); best=sum-s/ex.fi; rep(i,1,m) { if(ok[i]) { ll now=sum; pii better=max_lca(u[i],v[i]); now-=better.fi; now+=w[i]-s/c[i]; if(now<best) { best=now; ex=better; ey=mp(c[i],i); } } } printf("%lld\n",best); for(int x:ans) { if(x==ex.se) { if(!ey.se)printf("%d %d\n",x,w[x]-s/c[x]); } else printf("%d %d\n",x,w[x]); } if(ey.fi)printf("%d %d\n",ey.se,w[ey.se]-s/c[ey.se]); //system("Pause"); return 0; }