【UVALive】7338 Toll Management IV
来源:互联网 发布:网络探案小说排行榜 编辑:程序博客网 时间:2024/06/18 04:13
Discription
就给个大意了:给定一张图,问每条边最多能增加和减少多少,使得原本的最小生成树还是最小生成树。
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 200003typedef long long ll;int dep[N],d[N][15],g[N][14],tag[N][14],tot,T,n,m,s[N],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); }}
0 0
- 【UVALive】7338 Toll Management IV
- UVALive 7338 C - Toll Management IV
- UVA 1728 Toll Management IV
- UVALive 4302 Toll Road
- UVALive 4048 Fund Management
- UVALive 5067 Membership Management
- light oj 1379 - Toll Management(两次最短路)
- uvalive 2238 Fixed Partition Memory Management (KM)
- UVALive 4048 Fund Management(状压DP)
- UVALive 2238 Fixed Partition Memory Management(建图、KM)
- Toll University
- IV
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- C++中内存泄漏的几种情况
- TextWatcher 参数详解
- Fragment详解之三——管理Fragment(1)
- 程序员面试金典: 9.9 递归和动态规划 9.1上楼的方式
- 程序员面试金典: 9.9 递归和动态规划 9.1上楼的方式
- 【UVALive】7338 Toll Management IV
- Fragment详解之四——管理Fragment(2)
- UML用例图
- 1.安卓基础——哪里不懂写哪里,没有顺序没有规则,哈哈……
- struts2的contextmap和valueStack
- Mac Xcode崩溃 (打开ios项目引起崩溃)
- 用keil创建汇编工程时,选择出来器之后,不要加载启动项
- Fragment详解之五——Fragment间参数传递
- Codeforces Round #390 (Div. 2)-B Ilya and tic-tac-toe game(模拟)