題意:
有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 ...