標籤: 考試
本次考試排名:rank23
本次考試題目推薦:數字遊戲(細節巨多),麥樂雞翅(可後悔堆)
板子:次小生成樹(資料較弱)
今天沒有心路歷程(angry)
對自己算作一次警告吧
認識到了游泳的巨大安全隱患之後,小朋友們都決定不去游泳了。於是,游泳館冷清了下來。為了能因時制宜、因事制宜,游泳館決定在游泳專案之外,還開設頭腦風暴專案。頭腦風暴當中有這樣一道題目:給出乙個len位的數字a,你可以刪除數字a當中的n位,刪除之後得到乙個len-n位的數字b,你的目標就是使這個數字b最小。
對於 50%的資料,len<=100000.對於 100%的資料,len<=5000000 , 0<=n<=len.
利用單調棧,從前往後盡力去維護遞增,只要仍有刪除次數就維護下去。說白了是貪心即可(每次刪除左邊第乙個比右邊大的)好了,上**
int max=cnt-n;
for(int i=1;i<=cnt;i++)
if(!flag)puts("0");
在太行山路上,有一家麥樂雞翅的生意火爆。因為好吃,所以賣的特別好。排隊的人就特別多,經常有很多人買不到雞翅。雞翅會在每分鐘烤出xixi個,每分鐘也只會賣給乙個客人,第i個客人需要買yiyi
個。因為生意火爆,老闆可以選擇在這分鐘不賣給這個客人雞翅,或者賣給這個顧客他需要的雞翅,如果現在剩餘的雞翅不夠,那就肯定不能賣給這個客人。無論這個客人能否買到雞翅,他必須離開隊伍。現在給定 n 分鐘,且已經知道每分鐘烤出的雞翅個數xixi
,也知道每個客人需要雞翅的yiyi
個數,現在老闆想知道,如何合理安排賣給與拒絕,最多可以滿足多少人
50% 資料保證 n<=1000100% 1<=n<=250000 xi,yi 都在[0,10^9]範圍內
弄乙個大根堆出來,然後後悔就ok了,甚是簡單(那你怎麼不現切)
rg ll sum=0,now;
for(rg int i=1;i<=n;i++)
else
if(b[i]sum+=now-b[i];
chi.pop();
chi.push(b[i]);
}}rg int ans=chi.size();
cout《小 c 最近學了很多最小生成樹的演算法,prim演算法、kurskal演算法、消圈演算法等等。 正當小c洋洋得意之時,小p又來潑小c冷水了。小p說,讓小c求出乙個無向圖的次小生成樹,而且這個次小生成樹還得是嚴格次小的,也就是說:如果最小生成樹選擇的邊集是em,嚴格次小生成樹選擇的邊集是 es,那麼需要滿足:(value(e) 表示邊 e 的權值)
資料中無向圖無自環;
50% 的資料 n≤2 000 m≤3 000;
80% 的資料 n≤50 000 m≤100 000;
100% 的資料 n≤100 000 m≤300 000 ,邊權值非負且不超過 10^9 。
最小生成樹與次小生成樹一定只有一條邊的長度不同(證明感性思考一下就好了),因而我們要先構出一棵最小生成樹,然後再從邊集中選入某條邊以此來代替最小生成樹上的邊。由於我們新加入的邊所連線的兩點x,y必定是在同乙個集合中的了,因而我們考慮將x->y路徑上某條邊斷掉,那麼為了使修改後的邊權和盡可能接近最小生成樹的邊權和,我們查詢x->y路徑上的最大值,因而這個可以用倍增或樹剖+線段樹完成(筆者用的是倍增)
但是!!!(這個題目這麼簡單就太天真了!)會存在如下情況
有多組最小生成樹滿足條件
因而我們還需要維護乙個次大值,在有多組最大滿足下輸出次大就好了!這樣是不是可以解決問題了!好了,還有一些細節要處理,筆者放在**裡了,希望對大家有幫助(這個題目要思想有思想,要難度有難度,要細節有細節)
#include
#include
#include
#include
using
namespace
std;
#define rg register
#define ll long long
#define inf 1e18
const
int maxn=3e5+5;
int n,m;
ll ans=inf,s;
inline
int read()
struct edgee[maxn];
inline
bool cmp(edge a,edge b)
struct handa[maxn<<1];
int head[maxn],cnt,tot;
inline
void link(int u,int v,int z)
; head[u]=cnt;
}int dep[maxn],f[maxn][26];
ll g1[maxn][26],g2[maxn][26];
void dfs(int u,int fa)
}inline
void kru()
if(cao==n-1)break;
}}inline
void match(int &u,int j,ll &maxx,ll &semx)
else
if(maxxelse
u=f[u][j];
}inline ll lca(int u,int v,int stand)
return maxx;
}for(rg int j=20;j>=0;j--)
}match(u,0,maxx,semx);match(v,0,maxx,semx);
if(semx==-inf)return -inf;
if(maxx==stand)return semx;
return maxx;
}int main()
; for(rg int i=1;i<=n;i++)bcj[i]=i;
sort(e+1,e+m+1,cmp);
for(rg int i=0;i<=20;i++)g1[1][i]=g2[1][i]=-inf;
kru();dep[1]=1;dfs(1,0);
for(rg int j=1;j<=20;j++)
else}}
rg int x,y;
for(rg int i=1;i<=m;i++)
cout
0;}
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...
次小生成樹
演算法引入 設g v,e,w 是連通的無向圖,t是圖g的一棵最小生成樹 如果有另一棵樹t1,滿足不存在樹t t t1 則稱t1是圖g的次小生成樹 演算法思想 鄰集的概念 由t進行一次可行交換得到的新的生成樹所組成的集合,稱為樹t的鄰集,記為n t 設t是圖g的最小生成樹,如果t1滿足 t1 min,...
次小生成樹
分類 圖論 2013 02 12 15 03 32人閱讀收藏 舉報次小生成樹 在求最小生成樹時,用陣列path i j 來表示mst中i到j最大邊權。求完後,直接列舉所有不在mst中的邊,把它加入到mst中構成一棵新的樹,且該樹有環,此環是由剛加入的邊 i,j 造成的,所以可以通過刪除path i ...