10月3號 蒟蒻日記
本來從昨天開始就想記錄一下國慶這幾天的 奧賽生活(結果因為懶。。
那就從今天開始好了(結果今天才剛開始
------------------------------------------------------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"
10月3號 蒟蒻日記