codeforces #378F(733.F) Drivers Dissatisfaction
来源:互联网 发布:informix导出数据库 编辑:程序博客网 时间:2024/06/05 11:04
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 91 3 1 1 3 1 2 2 24 1 4 2 2 5 3 1 61 21 32 32 42 53 53 64 55 67
01 13 16 17 28 -5
3 39 5 17 7 22 13 13 22
53 02 5
题目大意:n个点m条边的图,每条边有边权wi和边权减1的费用ci
你有S的总费用,让你减少一些边的边权,使得生成的最小生成树的权值总和最小
首先可以确定,我们肯定就只会减少一条边的权重,因为如果减少两条边的权重,如果他们费用相等,那显然只需要减少一条边就好了;如果他们费用不等,那么肯定只减少权重小的那条边更优
那么我们先建立最小生成树,然后枚举要减的边
如果边在树上则直接在sum中减去
如果边不在树上,假设两边是s,t,那么在树上找到s,t中间路上权值最大的边删去,加上这条边即可。这里可以用倍增LCA来维护
在枚举的时候顺便记录方案则可输出最终方案
#include<map>#include<queue>#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<algorithm>using namespace std;struct line{ int s,t; long long x,c; int p; int next;}exa[200001],a[400001];int head[200001];int edge;inline void add(int s,int t,long long x,long long c){ a[edge].next=head[s]; head[s]=edge; a[edge].s=s; a[edge].t=t; a[edge].x=x; a[edge].c=c;}inline bool cmp1(line x,line y){return x.x<y.x;}inline bool cmp2(line x,line y){return x.p<y.p;}bool v[200001];int deep[200001];int ans[200001][22];long long anc[200001][22];int anx[200001][22];inline void bfs(int r){ int i,j; deep[r]=1; for(i=0;i<=21;i++) ans[r][i]=r; queue <int>Q; while(!Q.empty()) Q.pop(); Q.push(r); v[r]=true; while(!Q.empty()) { int d=Q.front(); Q.pop(); for(i=head[d];i!=0;i=a[i].next) { int t=a[i].t; if(!v[t]) { v[t]=true; Q.push(t); deep[t]=deep[d]+1; ans[t][0]=d; anc[t][0]=a[i].x; anx[t][0]=a[i].p; int dt;long long dc; for(j=1;j<=21;j++) { dt=ans[t][j-1]; dc=anc[t][j-1]; ans[t][j]=ans[dt][j-1]; if(anc[dt][j-1]>dc) { dc=max(dc,anc[dt][j-1]); anc[t][j]=dc; anx[t][j]=anx[dt][j-1]; } else { anc[t][j]=dc; anx[t][j]=anx[t][j-1]; } } } } }}long long ansx;struct xx{long long x;int p;};xx ax;inline int swim(int x,int y){ int ansc=0; while(deep[x]!=deep[y]) { int i=0; while(deep[ans[y][i]]>deep[x]) i++; if(i!=0) i--; if(anc[y][i]>ansx) { ansx=max(anc[y][i],ansx); ansc=anx[y][i]; } y=ans[y][i]; } ax.x=ansx; ax.p=ansc; return y;}inline xx lca(int x,int y){ ax.p=0; ax.x=0; ansx=0; int ansc=0; if(deep[x]>deep[y]) { int t=x; x=y; y=t; } y=swim(x,y); while(x!=y) { int i=0; while(ans[x][i]!=ans[y][i]) i++; if(i!=0) i--; // if(anc[x][i]!=xx) if(anc[x][i]>ansx) { ansx=max(anc[x][i],ansx); ansc=anx[x][i]; } //if(anc[y][i]!=xx) if(anc[y][i]>ansx) { ansx=max(anc[y][i],ansx); ansc=anx[y][i]; } x=ans[x][i]; y=ans[y][i]; } if(ansx>ax.x) { ax.x=ansx; ax.p=ansc; } return ax;}int fa[200001];inline int find(int x){ if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x];}long long w[200001],c[200001];int aa[200001];bool vv[200001];int main(){int n,m;scanf("%d%d",&n,&m);int i;for(i=1;i<=m;i++)scanf("%I64d",&w[i]);for(i=1;i<=m;i++)scanf("%I64d",&c[i]);for(i=1;i<=m;i++){scanf("%d%d",&exa[i].s,&exa[i].t);exa[i].x=w[i];exa[i].c=c[i];exa[i].p=i;}sort(exa+1,exa+1+m,cmp1);int sx=0;for(i=1;i<=n;i++)fa[i]=i;int p=0;long long ans=0,sum=0;for(i=1;i<=m;i++){int s=exa[i].s,t=exa[i].t;int fx=find(s),fy=find(t);if(fx!=fy){fa[fx]=fy;sx++;aa[sx]=exa[i].p;vv[exa[i].p]=true;sum+=exa[i].x;if(sx==n-1)break;}}sort(exa+1,exa+1+m,cmp2);ans=sum;for(i=1;i<=m;i++){if(!vv[i])continue;int s=exa[i].s,t=exa[i].t;long long w=exa[i].x,c=exa[i].c;edge++;a[edge].p=exa[i].p;add(s,t,w,c);edge++;a[edge].p=exa[i].p;add(t,s,w,c);}bfs(1);long long ss;scanf("%I64d",&ss);long long mini=0,minii=0;int flag=0;for(i=1;i<=m;i++){int s=exa[i].s,t=exa[i].t;if(vv[i]){if(sum-ss/exa[i].c<ans){ans=sum-ss/exa[i].c;mini=i;flag=1;}}else{xx ax=lca(s,t);if(sum-ax.x+exa[i].x-ss/exa[i].c<ans){flag=2;mini=i;minii=ax.p;ans=sum-ax.x+exa[i].x-ss/exa[i].c;}}}printf("%I64d\n",ans);if(flag==1){for(i=1;i<=m;i++){if(vv[i]){if(mini!=i)printf("%d %I64d\n",i,exa[i].x);elseprintf("%d %I64d\n",i,exa[i].x-ss/exa[i].c);}}}else{for(i=1;i<=m;i++){if(vv[i]&&i!=minii){printf("%d %I64d\n",i,exa[i].x);}else if(i==mini)printf("%d %I64d\n",i,exa[i].x-ss/exa[i].c);}}return 0;}
- codeforces #378F(733.F) Drivers Dissatisfaction
- codeforces 733F. Drivers Dissatisfaction
- Codeforces Round #378 (Div. 2) F. Drivers Dissatisfaction
- 【Codeforces 733F】 Drivers Dissatisfaction 【MST+bianry lifting】
- codeforces 733 F. Drivers Dissatisfaction(最小生成树+lca+倍增去环)
- CodeForces 733 F.Drivers Dissatisfaction(最小生成树-Kruskal+在线倍增法)
- 树链剖分,最小生成树(Drivers Dissatisfaction,cf 733F)
- Codeforces 659F F
- f
- f
- f
- f
- f
- F#
- f
- F
- f
- f
- Qt路径
- PyCharm取消波浪线、下划线和中划线
- PHP基础教程(九)字符串定义及单双引号的区别
- 1.3快速排序
- 欢迎使用CSDN-markdown编辑器
- codeforces #378F(733.F) Drivers Dissatisfaction
- js正则表达式
- 解决:Mybatis无法查询中文问题
- JavaSript模块化
- 初识ThreadPoolExecutor(二)——源码简单解读
- PHP基础教程(十)字符串定界符用法
- java正则中的反向取
- tableview自定义内容视图contentView及辅助视图accessoryType
- 修改环境变量PATH