【UVALive】7338 Toll Management IV
2017-01-08 13:01
351 查看
Discription
就给个大意了:给定一张图,问每条边最多能增加和减少多少,使得原本的最小生成树还是最小生成树。
Solution
思想:破环法
对于非树边,它可以无限增加(也不会成为生成树的一部分)
它最多能减少到它和这棵树构成的那个环中,除它自己以外最大边的长度
对于每条树边,它可以无限减少
它增加的范围是到其刚好可被替代,也就是所有包含这条边的环的最大边的最小值。
因为环由树边和非树边构成,所有非树边权值不小于树边
那么就可以说明,假如以两条(或以上)非树边和若干条树边构成了一个环,那么它对答案的限制不会强于以这些非树边分别和若干条树边构成的环。(因为限制由最长边贡献)
那么就可以通过维护链的最大值,以及对链取最小值两个操作,完成题目
(我写的倍增,懒癌晚期)
顺便推个大神,如果一直调不过的,他那里还有免费的造数据程序可以偷
http://blog.csdn.net/di4CoveRy/article/details/53509506
就给个大意了:给定一张图,问每条边最多能增加和减少多少,使得原本的最小生成树还是最小生成树。
Solution
思想:破环法
对于非树边,它可以无限增加(也不会成为生成树的一部分)
它最多能减少到它和这棵树构成的那个环中,除它自己以外最大边的长度
对于每条树边,它可以无限减少
它增加的范围是到其刚好可被替代,也就是所有包含这条边的环的最大边的最小值。
因为环由树边和非树边构成,所有非树边权值不小于树边
那么就可以说明,假如以两条(或以上)非树边和若干条树边构成了一个环,那么它对答案的限制不会强于以这些非树边分别和若干条树边构成的环。(因为限制由最长边贡献)
那么就可以通过维护链的最大值,以及对链取最小值两个操作,完成题目
(我写的倍增,懒癌晚期)
顺便推个大神,如果一直调不过的,他那里还有免费的造数据程序可以偷
http://blog.csdn.net/di4CoveRy/article/details/53509506
#include<stdio.h> #include<algorithm> #include<cstring> #define Min(a,b) a=min(a,b) #define Max(a,b) a=max(a,b) #define N 10003 #define M 200003 typedef long long ll; int dep ,d [15],g [14],tag [14],tot,T,n,m,s ,A[M],B[M],C[M]; ll S; using namespace std; struct edge{int v,c,n;}e[M]; inline void push(const int &a,const int &b,const int &c){e[++tot]=(edge){b,c,s[a]};s[a]=tot;} void dfs(const int &k,const int &f,const int &c) { dep[k]=dep[f]+1; d[k][0]=f;g[k][0]=c; for (int p=1;(1<<p)<dep[k];p++) { d[k][p]=d[d[k][p-1]][p-1]; g[k][p]=max(g[k][p-1],g[d[k][p-1]][p-1]); } for (int i=s[k];i;i=e[i].n) if (e[i].v!=f) dfs(e[i].v,k,e[i].c); } inline void solve(int u,int v,const int &c,const int &cas) { int ans=0; if (dep[u]<dep[v]) swap(u,v); for (int i=13;0<=i;i--) if ((1<<i)<=dep[u]-dep[v]) { Min(tag[u][i],c); Max(ans,g[u][i]); u=d[u][i]; } if (u!=v) { for (int i=13;0<=i;i--) if (d[u][i]!=d[v][i]) { Min(tag[u][i],c);Max(ans,g[u][i]); Min(tag[v][i],c);Max(ans,g[v][i]); u=d[u][i];v=d[v][i]; } Min(tag[u][0],c);Max(ans,g[u][0]); Min(tag[v][0],c);Max(ans,g[v][0]); } S+=-cas+(ll)cas*cas*(c-ans); } int main() { scanf("%d",&T); for (int t=1;t<=T;t++) { S=0; memset(s,0,sizeof(s)); memset(d,0,sizeof(d)); scanf("%d%d",&n,&m);tot=0; for (int i=1;i<n;i++) scanf("%d%d%d",A+i,B+i,C+i), push(A[i],B[i],C[i]),push(B[i],A[i],C[i]); for (int i=n;i<=m;i++) scanf("%d%d%d",A+i,B+i,C+i); dfs(1,0,0); memset(tag,0x3f,sizeof(tag));int inf=tag[0][0]; for (int i=n;i<=m;i++) solve(A[i],B[i],C[i],i); for (int p=13;p;p--) for (int i=1;i<=n;i++) if ((1<<p)<dep[i]) Min(tag[i][p-1],tag[i][p]),Min(tag[d[i][p-1]][p-1],tag[i][p]); for (int i=1;i<n;i++) { if (d[B[i]][0]==A[i]) swap(A[i],B[i]); S+=i*(tag[A[i]][0]==inf?-1:tag[A[i]][0]-C[i])-i*i; } printf("Case %d: %lld\n",t,S); } }
相关文章推荐
- UVALive 7338 C - Toll Management IV
- UVA 1728 Toll Management IV
- UVALive 2238 Fixed Partition Memory Management(建图、KM)
- UVALive 7338 (树链剖分+线段树)
- UVALive2238 Fixed Partition Memory Management
- UVALive 2238 Fixed Partition Memory Management(二分完美匹配)
- Fixed Partition Memory Management UVALive - 2238 建图很巧妙 km算法左右顶点个数不等模板以及需要注意的问题 求最小权匹配
- uvalive 2238 Fixed Partition Memory Management (KM)
- UVALive 2238 Fixed Partition Memory Management 固定分区内存管理(KM算法,变形)
- Corporative Network UVALive - 3027 并查集
- UVALive 3675 Sorted bit sequence(数位dp+二分)
- UVALive 4253 Archery(二分+atan2应用)
- UVALive 6910 Cutting Tree(并查集)
- 算法竞赛入门经典训练指南 例题1-15 网络 Network UVALive 3902
- UVa1006 - Fixed Partition Memory Management
- UVALive 6832 Bit String Reordering
- ZOJ1256 UVA602 UVALive5474 What Day Is It?【日期】
- UVALive - 3263 That Nice Euler Circuit (几何)
- UVALive 7146 Defeat the Enemy贪心
- UVALive 4978 Fields and Farmers