本来从昨天开始就想记录一下国庆这几天的 奥赛生活(结果因为懒。。
那就从今天开始好了(结果今天才刚开始
------------------------------------------------------8:23
需要从半夜时梦见帅气的学弟开始写起吗?(什么狗
需要从早上泡了一杯掺了奥利奥碎的原味咖啡写起吗?
需要从今天突然降温裹了一件外套来学校写起吗?
算了 老师来了 今天早上又是模拟考。。。
------------------------------------------------------8:31
离考试结束还有大概半个小时。。有点慌。。。
T1 图论题 EMM 先反向求两次最短路,然后再按拓扑序去DP,可是题目并没有保
证图中没有环啊(不知道会有多少分。。
T2 看起来像是树形DP,然而不会,按数据范围打了50分暴力(如果连50都没有。
。)
T3 好,完全懵逼。瞎推了一些神秘的性质,可是还是不知道怎么做啊,写了一个
根本不可能拿到分的骗分。。
最好的情况是拿到150分,也许连100分都没有。。
----------------------------------------------------11:35
老师还在给高一讲课,没空过来给我们评测 12:10
提交成功 12:13
原地爆炸 第一题才四十分,果然图是有环的! 12:22
来到学校 开始消化 14:51
T1 只要三遍最短路就可以解决啊啊啊啊 !
T1 完成-------15:13:06
T2 完成-------16:37:03
感觉T2的题解一点都不清晰 自己写一个好了
题目如下
【具有极强迷惑性又毫无用处的样例】
8 10 2 5 9 11 15 19 20 1 4 1 3 1 7 4 6 2 8 2 3 3 5
树形DP 那肯定要写出 DP方程啦 观察到n很小 所以
f[u][cu] 表示 假设此时距离u点最近的中心位于cu点,此时整个子树的费用之和(注意还没有加上在cu建立中心的K值)
然后每次更新的时候去找u 的所有直系儿子 设为 v 好了,可以用 f[v][cu] 直接更新,但如果离v最近的中心不是cu,而是是cv,那么就在v 的子树内部枚举所有的cv 找到一个最小的f[v][cv],用f[v][cv]+K 来更新,那为什么此时又加上K了呢?因为cv在v 的子树内,u的中心已经不是cv而是cu了,你这个cv被建为中心已经是板上钉钉的事,必须加上K。
然后可以用一遍Floyd处理出任意两点间的距离,代码如下
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 7 #define For(i,a,b) for(register int i=a;i<=b;++i) 8 #define Re register 9 #define inf 0x7f7f7f 10 using namespace std; 11 const int N=210; 12 int f[N][N]; 13 int d[N][N],dx[N]; 14 int head[N],nxt[N*2],v[N*2],cnt=0,nf; 15 int n,m,x,y,z,kx; 16 inline void read(int &v){ 17 v=0; 18 char c=getchar(); 19 while(c<‘0‘||c>‘9‘)c=getchar(); 20 while(c>=‘0‘&&c<=‘9‘)v=v*10+c-‘0‘,c=getchar(); 21 } 22 void add(int ux,int vx){ 23 cnt++; 24 nxt[cnt]=head[ux]; head[ux]=cnt; v[cnt]=vx; 25 cnt++; 26 nxt[cnt]=head[vx]; head[vx]=cnt; v[cnt]=ux; 27 } 28 29 int dfx[N],tot=0,bh[N],sz[N]; 30 void DFS(int x,int fa){ 31 dfx[++tot]=x; 32 sz[x]=1; bh[x]=tot; 33 for(Re int i=head[x];i;i=nxt[i])if(v[i]!=fa){ 34 DFS(v[i],x); 35 sz[x]+=sz[v[i]]; 36 } 37 } 38 39 void TrDP(int x,int fa){ 40 For(i,1,n)f[x][i]=dx[d[x][i]]; 41 for(Re int i=head[x];i;i=nxt[i])if(v[i]!=fa){ 42 int vv=v[i]; 43 TrDP(vv,x); 44 int mn=nf; 45 For(j,bh[vv],bh[vv]+sz[vv]-1){ 46 mn=min(mn,f[vv][dfx[j]]); 47 } 48 For(j,1,n)f[x][j]+=min(f[vv][j],mn+kx); 49 } 50 } 51 52 int main(){ 53 // freopen("ex.in","r",stdin); 54 freopen("logistics.in","r",stdin); 55 freopen("logistics.out","w",stdout); 56 read(n); read(kx); 57 For(i,1,n-1)read(dx[i]); 58 memset(d,inf,sizeof(d)); 59 nf=d[0][0]; 60 For(i,1,n-1){ 61 read(x); read(y); 62 add(x,y); 63 d[x][y]=d[y][x]=1; 64 } 65 66 For(i,1,n)d[i][i]=0; 67 For(k,1,n) For(i,1,n) For(j,1,n) 68 if(i!=j&&j!=k&&k!=i&&d[i][k]!=nf&&d[k][j]!=nf){ 69 d[i][j]=min(d[i][j],d[i][k]+d[k][j]); 70 } 71 72 73 DFS(1,0); 74 TrDP(1,0); 75 int fn=nf; 76 For(i,1,n)fn=min(fn,f[1][i]+kx); 77 cout<<fn<<endl; 78 fclose(stdin); fclose(stdout); 79 return 0; 80 }
17:13:25
18:33:30 回教室给桌上刚发芽的菊花浇了水,然后准备参加洛谷的模拟赛
21:55:23 还有35分钟结束,感觉还不错(?) 希望能拿到满分(?)
毕竟今天洛谷的运势可是大吉
22:34:45
AK了 不过有14个人AK呢 而且我是倒数第二的,不能太高兴,不能太高兴。。。。。
简略写一下思路吧(一定是因为 T2 开了没什么用的的三维DP数组 才慢的和狗一样)
T1 根据排列组合可以推出一个通式 Ans= n×2n-1-(2n-1) 就OK啦 不过草稿纸上的过程惨不忍睹
T2 DP题(开了三维的数组)f[i][j][0/1] 第 i 个Portal,时间到了j,第i个Portal 是否取,然后又开了一个Pa数组来记录是从哪里更新来的,最后从后往前去找出所有方案。
T3 本来以为NOIP不会考网络流的,想了二十几分钟的其它算法,后来才发现可以直接网络流建图(那些没学过网络流的NOIPer就有点可怜了)所以就把每个点拆成两个,建一个类似二分图的模型,流最大流判断是否有方案就OK了。最后还要在残流图上找到所有的方案,输出即可。
————————————23:00:59————————————
好了回家睡觉,今天就这样吧。
You can hear it in the silence~ silence~ you~~
You can feel it on the way home~ way home~ you~~
You can see it when the lights out~ light out~ you~~
——Taylor Swift "You Are in Love"
原文地址:https://www.cnblogs.com/HLAUV/p/9739113.html