noip膜你賽day2第二題 小G的煩惱

2021-08-04 07:29:07 字數 2638 閱讀 2242

題意:

有n座城市,m條雙向的航線連線它們,每一條航線有兩個值,分別是p,q,假設你付出x,y的花費那麼對於所有滿足p<=x&&q<=y的航線,都可以免費乘坐(其實題目本身來說是有乙個小彎的,就是說如果你付出的x,y並不能讓你乘坐那條航線,你也可以額外付這一條航線錢,但顯然,這是不優的),求最小花費(有自環和重邊)

題解:列舉第x,二分y,然後判斷圖是否聯通,理論上是80分的做法,但其實是可以ac的(資料水),這裡不做討論,而是討論出題人的滿分做法,這個做法真的十分巧妙

先轉換下問題:我們要做的就是在這m條邊中選出n-1條,使圖聯通,並且這些邊中的p的最大值和q的最大值之和最小

那麼現在就比較清晰了,可以發現,如果我們不下降地列舉p值(這裡也就是x),那麼如果找到了乙個能使圖聯通的q(這裡也就是y),那麼p值增大後這個q也自然是可以使圖聯通的,所以如果有新的q使圖聯通,最優值的q一定小於當前q,即:在以單調不下降的方式列舉q後,p值是單調不上公升的

膜拜gen4512大牛(不過話說為啥要取這個名字,貌似數字對應的漢字意思有點不對勁啊)

先附上考試時寫的80分**(裡面有我考試時想的思路),最小生成樹判聯通,m>5000時用明知道是錯的的兩次二分,唉,不想說話

80分code:

#include#include#include#include#include#includeconst int maxn=2005;

const int maxm=5005;

typedef long long ll;

using namespace std;

int n,m,cnt=1,fa[maxn],height[maxn];

int l,r,s,e,mid,ans,w,temp=0x3f3f3f3f;

int q[maxm];

struct nodeedge[maxm<<1];

inline void read(int &ret)

inline void addedge(int t1,int t2,int a,int b)

inline int root(int t)

inline void connect(int t1,int t2)

bool judge(int lima,int limb)

}return 0;

}bool check(int lima)

ans=q[(s+e)>>1];

return 1;

}int main()

sort(q+1,q+m+1);

if(n<=1)

if(m<5000)

else }

printf("%d\n",temp);}/*

???最小生成樹

問題轉換

首先對於這個問題來說,想要環遊所有城市

飛機所形成的線路一定是一顆樹,而問題可以

轉化成,要使這顆樹的兩個邊權最大值之和

最小樹形dp?

定義狀態dp[i]表示以i為根的子樹的邊權最大值之和

的最小值maxa[i],maxb[i]儲存以i為根的子樹的邊權

最大值不對啊,這個只是答案是個樹啊

圖論?cost[i][j]表示i到j的最小費用

不對,我還是覺得最小生成樹最靠譜

要不要套兩個二分?

第一次二分p[i],二分p[i]之後,check裡面二分q[i]

q[i]的check裡面用最小生成樹的思想判斷在不大於

p[i],q[i]的限制下,能否形成一顆樹,若能,返回1

不能返回0

算一下時間複雜度

兩次二分是log(p[i])*log(q[i])*mlogn

貌似能過誒

那會不會出現這種情況,就是第1個可以二分出較低

的答案,但是第二個就偏高,那麼第乙個就得列舉

所以說,現在的時間複雜度似乎應該是炸掉了

boom! 阿西吧,開啟騙分模式

哎,不過要是我把它優化成m*log(m)*m*log(n)勒

還是要炸啊,氣死我了

5 51 2 3 2

1 3 2 4

2 4 4 2

5 3 3 3

1 4 0 1

*/

正解:

#include#include#include#include#include#include#includeconst int maxn=2005;

const int maxm=5005;

using namespace std;

int fir[maxn],cnt=1;

int p[maxm],q[maxm];

int lima,limb,u,v,n,m;

struct nodeh[maxm<<1];

queueq; bool vis[maxn];

int ans=0x7f7f7f7f;

inline void read(int &ret)

inline void addedge(int t1,int t2,int p,int q)

inline bool bfs()

if(ncnt=n-1&&bfs())

limb=q[--j];

}printf("%d",ans); putchar(10);

}

noip膜你賽day2 總結

先膜拜一遍gen4512大牛 然後是總結 第一題,沒有選擇線段樹,因為我並沒有想到要去驗證azui具有結合律,不過交換率倒是去驗證過,很顯然失敗了,但後面我找到乙個規律,於是字首和直接搞定。成功ac。後來發現這道題的運算法則叫 同或 相同為1,相異為0 對於這種題,定義了一種新的運算,我認為,突破點...

noip膜你賽day2第一題

題意 有乙個由0和1組成的陣列,定義一種新運算azui,1 azui 1 1,1 azui 0 0,0 azui 1 0,0 azui 0 1,給出乙個長度為n的該陣列,以及m個查詢l,r,表示將區間 l,r 從l乙個乙個azui到r的值。題解 額,先說說稍微複雜一點的做法,可以發現,這個azui運...

l洛谷 NOIP提高組模擬賽 Day2

傳送門 t1 區間修改 單點查詢。差分樹狀陣列。include include include using namespace std const int maxn 10000005 inline intrd while isdigit ch return f?x x void out int x ...